[concurrency-interest] throwing RuntimeException vs Exception inThreadPoolExecutor

David Holmes davidcholmes at aapt.net.au
Sat May 29 19:43:09 EDT 2010


Kai Meder writes:
> I'm hacking in Scala and use the ThreadPoolExecutor. I use an Exception
> "TerminatedChannel", using the trait ControlThrowable, inside my tasks
> in for ControlFlow (please no discussion about this).
>
> When using TerminatedChannel as a RuntimeException it passes the
> attached ThreadPoolExector-CodeBlock. If used just as a Throwable the
> ThreadPoolExecutor suspends the thread, as TerminatedChannel
> broke its neck.
>
> Is this supposed Java-behaviour? Do I need to declare Exceptions as
> RuntimeExceptions to get propagated to the normal catch-clause?
>
> Any advice appreciated very much. Thanks!
>
>
> public void run() {
>             try {
>                 Runnable task = firstTask;
>                 firstTask = null;
>                 while (task != null || (task = getTask()) != null) {
>                     runTask(task);
>                     task = null;
>                 }
>             } finally {
>                 workerDone(this);
>             }
>         }

I don't quite understand your description, nor what the "normal
catch-clause" refers to.

In Java, exceptions (any type that extends Throwable) come in two flavours:
 - checked
 - unchecked
Unchecked exceptions are instances of Error or its subclasses, or instances
of RuntimeException or its subclasses. All other exception types are checked
exceptions.

Methods must declare all checked exceptions they throw in their throws
clause. The compiler will not allow methodA to call methodB if methodB
throws a checked exception and either methodA does not declare the same
exception, or methodA does not catch the checked exception thrown by
methodB.

It just occurs to me that perhaps you are mistakenly thinking that if a task
you submit to an executor throws an exception, then that exception will
somehow appear in the thread that did the submission? That will not happen
by itself. Exceptions are always local to a given Thread in Java. If you do
something that results in code executing in another thread, any exceptions
from that code impact only that other thread - unless you explicitly arrange
for it to be reported back to the original thread somehow. For example,
Future.get will throw ExecutionException if the computation (whichever
thread performed it) threw an exception - but that is because the Future
implementation has to catch and store the original exception so it can be
rethrown in the thread doing the get().

In the executor code you show, any uncaught exception from the task will
lead to termination of the executor worker thread and invocation of the
uncaught-exception handler for that thread.

David Holmes




More information about the Concurrency-interest mailing list