• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

java.util.Timer inside Runnable?

 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 147
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"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
Posts: 147
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 147
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 147
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
reply
    Bookmark Topic Watch Topic
  • New Topic