Reputation: 2975
If i am using Futures
like
List<Future<String>> results = executorService.invokeAll(tasks);
or
Future<String> res = executorService.submit(new SingleWorker());
System.out.println(res.get());
the system waits for the tasks to complete.
Even if i had executorService.shutdownNow();
after the statements mentioned above, i really don't understand when will the system forcefully terminate the existing threads as mentioned in the documentation since, the system never reaches the line until the tasks are completed and a future is returned.
Am i missing something ? Is there a different test case scenario to test it ?
Will shutdownNow
work only with Runnable
i.e. when we say
executorService.submit(new MyRunnable())
?
EDIT:
I tried few different things and found out that
a)shutdownNow
doesn't work with invokeAll
.
b)shutdownNow
if present after Future.get
then the statement shutdownNow
is blocked until Future
is resolved (In case of Callable
).
c)shutdownNow
works perfectly with Runnable
.
Following is my code written to test:
class SingleRunnableWorker implements Runnable {
@Override
public void run() {
System.out.println("SingleRunnableWorker Running..");
try {
Thread.sleep(10000);
System.out.println("SingleRunnableWorker Running after sleep..");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class SingleCallableWorker implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("SingleCallableWorker Calling..");
Thread.sleep(10000);
System.out.println("SingleCallableWorker Calling after sleep..");
return "SingleCallableWorker Calling done";
}
}
and i am testing it as follows:
ExecutorService executorService = Executors.newFixedThreadPool(4);
/*List<Future<String>> results = */executorService.invokeAll(tasks);//blocks by default
Future<String> res = executorService.submit(new SingleCallableWorker());
//System.out.println(res.get()); //blocks if uncommented
executorService.submit(new SingleRunnableWorker());
executorService.shutdownNow();
where tasks are all Callables
.
Bottomline is invokeAll
and Future.get
are blocking operations. Can someone please validate ?
Upvotes: 0
Views: 102
Reputation: 28269
Both Runnbale
and Callable
you submitted to ThreadPoolExecutor
will be wrappered as java.util.concrrent.FutureTask
and executed.
In this case, in both SingleRunnableWorker
and SingleCallableWorker
, when task is blocked by Thread.sleep(10000)
, executorService.shutdownNow()
will cause InterruptedException be thrown immediately.
But,
InterruptedException
thrown in SingleRunnableWorker.run()
is
forced to be catched immediately and handled by e.printStackTrace()
.InterruptedException
thrown in SingleCallableWorker.call()
will
be catched by inner syncronizer in FutureTask
, the syncronizer just
record InterruptedException and return. When future.get()
is called, the
InterruptedException will be wrappered as ExecutionException and
re-thrown.Upvotes: 1