Reputation: 384
I am using an ExecutorService for a connection task as below:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<ApplicationConnection> future = (Future<ApplicationConnection>) executor.submit(new ConnectThread(crf, connoptions));
connection = future.get(300000, TimeUnit.SECONDS);
executor.shutdownNow();
The call()
method calls a .connect()
method (proprietary API). This connect method spawns various threadpools etc. My concern is that if the future times out and kills the executor, will the threads that may have already spawned by calling the .connect()
method in the future also end? I know that killing a thread will also kill any child threads but does this follow the same logic?
Upvotes: 0
Views: 778
Reputation: 341003
You are right in your assumption, if the Future
times out, some hanging threads will remain. Even worse, shutdownNow()
will not even shutdown your pool thread (not to mention proprietary API threads). It merely stops accepting new jobs. ExecutorService
thread pool will terminate all threads once all running tasks finish.
What you can do is to try canceling the future and interrupting it. First handle InterruptedException
inside your future:
class ConnectThread implements Callbale<ApplicationConnection> {
public ApplicationConnection call() {
try {
return prioprietaryApi.connect();
} catch(InterruptedException e) {
prioprietaryApi.cleanUp();
throw e;
}
}
}
Now simply run:
future.cancel(true);
However your proprietary API might not handle InterruptedException
(it will not rethrow it from connect()
, moreover you might not have access to any cleanUp()
method.
In these circumstances just... forget about it. That Future
will eventually terminate and clean up after itself, ignoring the fact that you no longer wait for it. Of course this might lead to various scalability issues.
BTW if the only thing you want to achieve is limiting the maximum time given method runs, consider TimeLimiter
from guava.
Upvotes: 2
Reputation: 66677
As per javadoc
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution. 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.
Upvotes: 1