Killing thread after some specified time limit in Java
Make use of ExecutorService
to execute the Callable
, 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 Callable
.
java killing a thread after timeout value
It's the same problem like this. Please use ExecutorService
to execute the Runnable
How do I force terminate a thread in java with time limit?
Code snippet that I've used to do something similar:
LOG.info("Time limited task started on monitored thread, with limit (" + limit + ")");
final ZonedDateTime start = nowUTC();
final Thread thread = new Thread(toRun);
thread.setDaemon(true);
final List<Throwable> exceptions = new ArrayList<>();
thread.setUncaughtExceptionHandler((t, e) -> {
exceptions.add(e);
});
thread.start();
// Check and wait for completion.
while (thread.isAlive()) {
if (!isWithinLimit(start, nowUTC())) {
LOG.error("Interrupting thread, did not complete before limit (" + limit + ")");
try {
thread.interrupt();
} catch (Exception e) {
e.printStackTrace();
}
throw new TimeLimitExceedException("Execution limit of " + limit
+ " exceeded. (Has been running since " + start + ")");
}
try {
Thread.sleep(POLLING_PERIOD.toMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// If it failed because of an exception, we want to trigger this.
if (!exceptions.isEmpty()) {
final Throwable exception = exceptions.get(0);
if (exception instanceof RuntimeException) {
throw (RuntimeException) exception;
} else {
throw new RuntimeException(exception);
}
}
final Duration runTime = Duration.between(start, nowUTC());
LOG.info("Time limited task has completed in (" + runTime + ") vs limit of (" + limit
+ ").");
TLDR:
I just start whatever I'm running as a new thread that is set as a daemon (just in case it is the last thing running), then I get a reference to that and poll it, and call thread.interrupt() if it goes over the time limit.
Other context & bells and whistles
- This is part of a class that has some other state, like duration and what it is running
- Also track some exceptions so that it can be spit out at the end if necessary
How to timeout a thread
Indeed rather use ExecutorService
instead of Timer
, here's an SSCCE:
package com.stackoverflow.q2275443;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(3, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
future.cancel(true);
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
class Task implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(4000); // Just to demo a long running task of 4 seconds.
return "Ready!";
}
}
Play a bit with the timeout
argument in Future#get()
method, e.g. increase it to 5 and you'll see that the thread finishes. You can intercept the timeout in the catch (TimeoutException e)
block.
Update: to clarify a conceptual misunderstanding, the sleep()
is not required. It is just used for SSCCE/demonstration purposes. Just do your long running task right there in place of sleep()
. Inside your long running task, you should be checking if the thread is not interrupted as follows:
while (!Thread.interrupted()) {
// Do your long running task here.
}
How to limit a thread's execution time and terminate it if it runs too long?
I would use an ExecutorService
to run the thread. Then I would get back a Future
and use get()
with a timeout to cancel it.
ExecutorService es = Executors.newFixedThreadPool(1); // You only asked for 1 thread
Future<?> future = es.submit( new Mythread() );
try {
future.get(timeout, TimeUnit.SECONDS); // This waits timeout seconds; returns null
} catch(TimeoutException e) {
future.cancel(true);
}
How to stop a thread after some time in java?
I don't know whether it is supported in Android, but this is exactly what the Future objects returned from an ExecutorService are supposed to do for you. In particular, the cancel(boolean) method can be used to interrupt the task if it has started but not finished.
The tasks should be written to be aware that they may be interrupted, and abort cleanly if they have been. Most of the framework IO methods can be interrupted, so you just need to worry about your own code.
Related Topics
Java Leaking This in Constructor
Expression Language in Jsp Not Working
Best Java/Swing Browser Component
How Does Synchronized Work in Java
Serving Static Files from Alternate Path in Embedded Jetty
How to Match String Within Parentheses (Nested) in Java
Printwriter Append Method Not Appending
Differencebetween a Local Variable, an Instance Field, an Input Parameter, and a Class Field
Possible Causes of Java Vm Exception_Access_Violation
How to Write an Rss Feed with Java
Does Java Evaluate Remaining Conditions After Boolean Result Is Known
Get Variable by Name from a String
Gson Throws Malformedjsonexception
List of Useful Environment Settings in Java
Subclassing a Java Builder Class