I'm using Executors.newCachedThreadPool()
and invokeAll
with a List of Callable
s to do long-running multithreaded processing.
My main thread is blocked until all threads did finish and I can process the Futures returned by invokeAll
. I'd like however invokeAll
to immediately return if one of the Callable
s throw an exception and terminate the other threads.
Using execute
instead of invokeAll
would block on the first future.get()
which needs not to be the one that throws the execption.
Using busy waiting to loop through all the futures and checking isDone()
seems not to be the best way either.
Yes. "this gets printed before the system. out. println() in the child threads.
An uncaught exception will cause the thread to exit. When it bubbles to the top of Thread. run() it will be handled by the Thread's UncaughtExceptionHandler. By default, this will merely print the stack trace to the console.
Explanation: By calling sleep() within main(), with long enough delay to ensure that all child threads terminate prior to the main thread. 2.
You can use more complex synchronization mechanisms like latches, barriers or semaphores, but have a look at ExecutorCompletionService
. It's a lightweight wrapper around ExecutorService
that allows you to listen for the first finished task. Here is a quick example:
final ExecutorService executorService = Executors.newCachedThreadPool();
final ExecutorCompletionService<String> completionService =
new ExecutorCompletionService<String>(executorService);
for (int i = 0; i < 10; ++i) {
completionService.submit(new Task());
}
completionService.take().get();
The code is pretty simple. First you wrap executorService
with completionService
. Later you use it to submit tasks one after another. The last line is crucial. It takes the first task that finished and tries to retrieve the result. If it thrown an exception, it will be rethrown here, wrapped with ExecutionException
:
try {
completionService.take().get();
} catch (ExecutionException e) {
e.getCause(); //this was thrown from task!
}
Inside catch
block you can somehow handle the exception, e.g. canceling remaining tasks or shutting down the whole thread pool.
Of course you are free to wait for all tasks to finish by calling take()
ten times. Each call will block as long as there is at least one task finished.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With