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?
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.
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.
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
.
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.
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.
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...}