Greg
Greg

Reputation: 384

shutdownNow with executor service

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

Answers (2)

Tomasz Nurkiewicz
Tomasz Nurkiewicz

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 .

Upvotes: 2

kosa
kosa

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

Related Questions