Reputation: 687
Am learning about ExecutorService introduced in Java 1.5
The following example seems to defy expected behaviour :
public static void main(String[] args) throws InterruptedException,
ExecutionException,TimeoutException {
Callable<String> task = () -> {
int counter = 0;
while(true) {
//infinite loop will never exit
if(counter == 7) {
break;
}
}
return "abc";
};
ExecutorService service = Executors.newSingleThreadExecutor();
try {
Future<String> future = service.submit(task);
System.out.println("result = " + future.get(10000,TimeUnit.MILLISECONDS));
}finally {
System.out.println("<<<< finally >>>>");
service.shutdownNow();
}
}
Looking at java docs for this method:
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt, so any task that fails to respond to interrupts may never terminate.
So ideally what I was expecting was that after specified timeout I would get a Timeout exception and then the ExecutorService would shutdown forcefully but that does not happen.
Looked at the java doc - and it does seem to indicate that there is no guarantee that it would shutdown.
If its not guaranteed then should it be avoided ?
Upvotes: 0
Views: 788
Reputation: 718678
Looked at the java doc - and it does seem to indicate that there is no guarantee that it would shutdown.
Correct.
If its not guaranteed then should it be avoided ?
No.
What you should actually be doing is to use ExecutorService
in a way that avoids or works around the limitations; e.g.
Implement any tasks that may be long running and that should be killable so that they do handle interrupts correctly. If you do that correctly, then your ExecutorService
will terminate.
Don't depend on the ExecutorService
actually shutting down. For example, you could arrange that when the application needs to shutdown, it does the following:
shutdownNow()
awaitTermination(...)
with an appropriate timeoutExecutorService
doesn't terminate then it calls System.exit(...)
to terminate the application.Configure your ExecutorService
to create the worker threads as daemon threads; see Turning an ExecutorService to daemon in Java.
A daemon thread won't prevent the JVM from exiting. But note that you need to be careful. If all non-daemon threads have finished, the JVM will pull the plug without interrupting any tasks that the ExecutorService
is currently running.
Upvotes: 2