This week's book giveaway is in the Jobs Discussion forum.
We're giving away four copies of Soft Skills and have John Sonmez on-line!
See this thread for details.
The moose likes Threads and Synchronization and the fly likes java.util.Timer inside Runnable? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "java.util.Timer inside Runnable?" Watch "java.util.Timer inside Runnable?" New topic
Author

java.util.Timer inside Runnable?

trebor iksrazal
Greenhorn

Joined: Jun 28, 2004
Posts: 7
I want to do an operation inside a Runnable that could time out. I want to have several of these running at the same time. Timer/Timer task typically works like:

Thread task = new Thread(new Task());
TimerOut to = new TimerOut(task); //extends TimerTask
new Timer(true).schedule((TimerTask) to,TIMEOUT);
task.start();

However, I can't call Thread.start() inside a Runnable. Here's my idea, but unfortunately it never completes.

import java.util.*;
import java.io.*;

public class RunnableTimer
{
class MyRunnable implements Runnable
{
public void run()
{
java.util.TimerTask task = new TimerTask()
{
Thread thread = Thread.currentThread();
public void run()
{
System.out.println("Inside TimerTask run...");
thread.interrupt(); // interrupt work
}
};

Timer timer = new Timer();
timer.schedule(task, 3000);
try
{
// do interruptible work ...
System.out.println("Inside MyRunnable...");
}
finally
{
task.cancel();
Thread.interrupted(); // clear interrupt flag
}
}
}

public static void main(String args[])
{
new RunnableTimer();
}

public RunnableTimer()
{
try
{
(new Thread(new MyRunnable())).start();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

Any help would be greatly appreciated.
iksrazal
Yaroslav Chinskiy
Ranch Hand

Joined: Jan 09, 2001
Posts: 147
I dont this you use the Timer object proparly.

U need to have Runnable to start by timer. Timer is a thread. So once you pass
task to the Timer, it will run at the scheduled time. You dont need to pass it a thread and try to start that thread later.


If you need to make sure that ur task does not run if some conition is not met
then just put a check for the condition inside the run() method of that task.
trebor iksrazal
Greenhorn

Joined: Jun 28, 2004
Posts: 7
"U need to have Runnable to start by timer. Timer is a thread. So once you pass task to the Timer, it will run at the scheduled time. You dont need to pass it a thread and try to start that thread later."

Actually in the traditional timer example I gave, it times out:

class TimerOut extends TimerTask {

Thread threadToTimeOut;

public TimerOut(Thread threadToTimeOut) {
this.threadToTimeOut = threadToTimeOut;
}

public void run() {
System.out.println("TimerOut running...");
threadToTimeOut.interrupt();
}
}

At the scheduled time, instead of running a task, I want to call Thread.interrupt() and cancel the operation.

What I want is the task that does the work, MyRunnable, to time out. Now I can do this by using the traditional example, by passing MyRunnable to the timer as you suggest:

Thread task = new Thread(new MyRunnable());
TimerOut to = new TimerOut(task);
new Timer(true).schedule((TimerTask) to,TIMEOUT);
task.start();

This works. But that only allows for one thread. What I want is multiple threads from a thread pool, working on MyRunnable. For example:

PooledExecutor pe = new PooledExecutor(3);
pe.execute(new MyRunnable());
pe.execute(new MyRunnable());
pe.execute(new MyRunnable());

How can I have multiple threads that can timeout a Runnable?
iksrazal
Yaroslav Chinskiy
Ranch Hand

Joined: Jan 09, 2001
Posts: 147
I still dont get what you need.

U can not create method in MyRunnable() that uses Thread.currentThread(). Because that will return a reference to the Thread that calls the method and not to the Thread that runs the Runnable object.

U can create ur own ThreadPool and only use it for MyRunnable. In the pool object create a method that returns Set of all active thread and call interrupt on them.

http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/PooledExecutor.html

Why are u trying to use Timer?
trebor iksrazal
Greenhorn

Joined: Jun 28, 2004
Posts: 7
I appreciate your help. Sorry if I'm not expressing my self clearly.

"Why are u trying to use Timer?"

I have two problems:

1) I need to do multiple client socket invokations simulatenously, which can time out.
2) I want to use threads for these calls.

I can get sockets to time out:

import java.util.Timer;
import java.util.TimerTask;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.io.*;

/**
Times out a socket using nio
*/
class NIOTest extends Object
{
static final int TIMEOUT = 10000;

public static void main(String[] args)
{
Thread task = new Thread(new Task());
TimerOut to = new TimerOut(task);
new Timer(true).schedule((TimerTask) to,TIMEOUT);
System.out.println(TIMEOUT + " milliseconds to socket timeout...");
task.start();
}

static class TimerOut extends TimerTask
{
Thread threadToTimeOut;

public TimerOut(Thread threadToTimeOut)
{
this.threadToTimeOut = threadToTimeOut;
}

public void run()
{
System.out.println("TimerOut running...");
threadToTimeOut.interrupt();
}
}

static class Task implements Runnable
{
Charset ascii = Charset.forName("US-ASCII");
String sendme;

public Task ()
{
;
}

public Task (String var)
{
this.sendme = var;
}

public void run()
{
SocketChannel sChannel = null;
try
{
// Create a non-blocking socket channel on port 2510
sChannel = createSocketChannel("10.200.200.144", 2510);

// Before the socket is usable, the connection must be completed
// by calling finishConnect(), which is non-blocking
while (!sChannel.finishConnect())
{
Thread.sleep(100);
// Do something else
}

Thread.sleep(5000);
System.out.println(readFromChannel(sChannel));
Thread.sleep(15000);
}
catch (Exception e)
{
if (e instanceof InterruptedException)
{
System.err.println("Connecton timed out!");
}
else
{
e.printStackTrace();
}
}
finally
{
try
{
if (null != sChannel)
{
sChannel.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

public SocketChannel createSocketChannel(String hostName, int port) throws IOException
{
// Create a non-blocking socket channel
SocketChannel sChannel = SocketChannel.open();
sChannel.configureBlocking(false);
// Send a connection request to the server; this method is non-blocking
sChannel.connect(new InetSocketAddress(hostName, port));
return sChannel;
}

private void writeToChannel (SocketChannel sChannel, String send) throws IOException
{
CharBuffer cbuf = CharBuffer.wrap(send);
ByteBuffer buf = this.ascii.encode(cbuf);
sChannel.write(buf);
}

private String readFromChannel (SocketChannel sChannel) throws IOException
{
CharsetDecoder decoder = this.ascii.newDecoder();
ByteBuffer buf = ByteBuffer.allocate(1024);

sChannel.read(buf);
buf.flip();
CharBuffer cbuf = ascii.decode(buf);
return cbuf.toString();
}
}
}

Excuse the nio, but this is a simple example. It reads the data successfully
and then simulates a timeout.

Now, _WHY_ did I think I can do this in PooledExecutor?

http://altair.cs.oswego.edu/pipermail/concurrency-interest/2003-June/000459.html

It's a simple example, but I thought was possible to do this. Maybe not.

Thanks for your paitence,
iksrazal
Yaroslav Chinskiy
Ranch Hand

Joined: Jan 09, 2001
Posts: 147
Oh.. I think I get it now
I do the ame thing it sockets.


Here is example of what may work.



Let me know if that is what u were looking for
[ July 01, 2004: Message edited by: Yaroslav Chinskiy ]
trebor iksrazal
Greenhorn

Joined: Jun 28, 2004
Posts: 7
This seems to be something that can work. Thanks!

I have two questions I am trying to solve on my own. Perhaps you can explain:

1)

if(t!= null || t1.isActive())

This doen't compile because t1 is not in scope, and also Thread does not have an isActive() method. Sometimes socket implementations have an isActive(), or perhaps you meant isAlive() - I'm not sure.

2) This code catches the Interrupted exception in the Runnable, but never exits. I'm not sure how to force an exit here.

Outside of that, I do appreciate everything and I'm working through your idea.

Thanks again!
iksrazal
Yaroslav Chinskiy
Ranch Hand

Joined: Jan 09, 2001
Posts: 147
Ops. my mistake.

I wanted to type t.isAlive()

The code never exits because the Timer object is a thread and JVM does not exist while at least one non daemon thread is alive.

I am not sure how you need to handle this but for the example you can use this:



Hope that helps
[ July 01, 2004: Message edited by: Yaroslav Chinskiy ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: java.util.Timer inside Runnable?