[concurrency-interest] Thread.uncaughtExceptionHandler is not called in ScheduledThreadPool/ThreadPool-executors

Aleksey Shipilev aleksey.shipilev at gmail.com
Tue Apr 26 16:25:57 EDT 2011

Ah, so this is because we reuse worker threads? Then yes, we will
break semantics of Thread.UncaughtExceptionHandler if we propagate
that exception down the path. Makes sense. Catching, logging, and
rethrowing Throwable in CheckedRunnable seems to be better solution.


On Wed, Apr 27, 2011 at 12:18 AM, Ariel Weisberg <ariel at weisberg.ws> wrote:
> Hi,
> Off the cuff I recall that this is because a future is returned and the
> exception is swallowed by the future. This is correct behavior for
> submit and schedule. See the note in
> http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html#afterExecute(java.lang.Runnable,
> java.lang.Throwable)
> There are some cases where a thread owned by the pool will allow the
> exception to bubble up to the handler (and the thread terminates). With
> a regular TPE it will happen if you invoke execute on a Runnable. With
> STPE it will never happen (even if you invoke execute on a Runnable)
> because it is always wrapped up in a future internally even if you
> invoke execute. STPE invokes schedule internally and schedule will wrap
> the Runnable in an exception swallowing future.
> You can implement a base class for your Runnables or FutureTasks that do
> the necessary wrapping to get the logging or error handling behavior you
> want and pass that your executors. This will get you uniform behavior
> across all the executors (TPE, STPE) and methods (submit, schedule,
> execute).
> Regards,
> Ariel Weisberg
> On Tue, 26 Apr 2011 23:22 +0400, "Aleksey Shipilev"
> <aleksey.shipilev at gmail.com> wrote:
>> Hi,
>> I've been recently stumbled upon the issue about
>> ScheduledThreadPoolExecutor. I was thinking that I can trace whether
>> my scheduled task experienced some fatal exception and dump that
>> exception to log. I had set my own ThreadFactory which creates the
>> threads with appropriate Thread.UncaughtExceptionHandler. However,
>> it's not being called when it's anticipated to.
>> Is there anything I miss? May be this is correct behavior, and I
>> should trace exceptional cases in some other way?
>> I don't really want to drag my Future<?> around just to handle this
>> logging case.
>> Attached patch against jsr166 trunk contains the test cases.
>> Apparently, ThreadPoolExecutor has the same issue. Both new test cases
>> are failing on my machine (Ubuntu 10.10 x86 i5-520M):
>>     [junit] Running ScheduledExecutorTest
>>     [junit] Tests run: 61, Failures: 1, Errors: 0, Time elapsed: 1.221
>>     sec
>>     [junit] Test ScheduledExecutorTest FAILED
>>     [junit] java version "1.6.0_24"
>>     [junit] Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
>>     [junit] Java HotSpot(TM) Server VM (build 19.1-b02, mixed mode)
>>     [junit] Running ThreadPoolExecutorTest
>>     [junit] Tests run: 102, Failures: 1, Errors: 0, Time elapsed: 0.86
>>     sec
>>     [junit] Test ThreadPoolExecutorTest FAILED
>>     [junit] java version "1.6.0_24"
>>     [junit] Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
>>     [junit] Java HotSpot(TM) Server VM (build 19.1-b02, mixed mode)
>> I've double-checked those tests pass when done.countDown() is being
>> done before throwing exception.
>> Thanks,
>> Aleksey.
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>> Email had 1 attachment:
>> + jsr166-unhandled-1.patch
>>   6k (text/x-patch)

More information about the Concurrency-interest mailing list