views:

363

answers:

6

Is there a way to kill a child thread after some specified time limit in Java? Edit: Also this particular thread may be blocked in its worst case (Thread is used to wait for a file modification and blocks until this event occurs), so im not sure that interrupt() will be successful?

+1  A: 

Why not interrupt() it after a particular time ? Your spawned thread will have to be able to handle an InterruptedException properly.

See this article (http://www.javaspecialists.eu/archive/Issue056.html) for more information on shutting down threads cleanly.

See also the Executor/Future framework, which provide useful methods for collecting results and/or terminating threads within particular time limits.

Brian Agnew
The thread only needs to respond to `InterruptedException` if it makes a call that can throw it. If it is spinning in a loop, it should be checking its own interrupted flag using `Thread.isInterrupted()` (or just `Thread.interrupted()`, implying the current thread).
Mike Daniels
A: 

Killing a thread is generally a bad idea for reasons linked to for the API docs for Thread.

If you are dead set on killing, use a whole new process.

Otherwise the usual thing is to have the thread poll System.nanoTime, poll a (possible volatile) flag, queue a "poison pill" or something of that nature.

Tom Hawtin - tackline
+2  A: 

Make use of ExecutorService to execute the Runnable, checkout the methods wherein you can specify the timeout. E.g.

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();

Here Task of course implements Runnable.

BalusC
Good suggestions, but will the ExecutorService be able to timeout the thread even if it is blocked?
Traker
It will interrupt the thread, yes. If you like to hook on it, make use of `ExecutorService#awaitTermination()`, also see the example in the Javadoc's introduction.
BalusC
A: 

Brian's right, interrupting it is safer than "stopping" the thread.
What if the thread is locking on an object mid-modification, and suddenly gets stopped (which causes the lock to be released)? You get weird results.

Ryan P.
A: 

Not directly; I think the simplest way is to join() on that thread with that time limit, and interrupt the thread if it's not done by the time the join ended.

So,

Thread t = ...
t.join(timelimit);
if (t.isAlive) t.interrupt();

Notice I used interrupt instead of actually killing it, it's much safer. I would also recommend using executors instead of directly manipulating threads.

Oak
A: 

Do not use destroy() since that does not perform any cleanup.

The most straightforward way is to use join(), like

try {
     thread.join();
} catch (InterruptedException e) {//log exception...}

You could use an ExecutorService. That would make a lot of sense if you have several threads running concurrently. If you have the need to spawn new threads while other threads are running, you can combine this with a BlockingQueue.

A ThreadPoolExecutor (an ExecutorService-implementation) can take a BlockingQueue as argument, and you can simply add new threads to the queue. When you are done you simply terminate the ThreadPoolExecutor.

private BlockingQueue<Runnable> queue;
...
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, new Long(1000), 
                TimeUnit.MILLISECONDS, this.queue);

You can keep a count of all the threads added to the queue. When you think you are done (the queue is empty, perhaps?) simply compare this to

 if (issuedThreads == pool.getCompletedTaskCount()) {
        pool.shutdown();
    }

If the two match, you are done. Another way to terminate the pool is to wait a second in a loop:

try {
      while (!this.pool.awaitTermination(1000, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {//log exception...}
Lars Andren