为什么ExecutorService不调用UncaughtExceptionHandler? [英] Why is UncaughtExceptionHandler not called by ExecutorService?
问题描述
我偶然发现了一个问题,可以总结如下:
I've stumbled upon a problem, that can be summarized as follows:
当我手动创建线程时(即通过实例化 java .lang.Thread
)适当调用 UncaughtExceptionHandler
。但是,当我使用带有 ThreadFactory
的 ExecutorService
时,处理程序被省略。我错过了什么?
When I create the thread manually (i.e. by instantiating java.lang.Thread
) the UncaughtExceptionHandler
is called appropriately. However, when I use an ExecutorService
with a ThreadFactory
the handler is ommited. What did I miss?
public class ThreadStudy {
private static final int THREAD_POOL_SIZE = 1;
public static void main(String[] args) {
// create uncaught exception handler
final UncaughtExceptionHandler exceptionHandler = new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
synchronized (this) {
System.err.println("Uncaught exception in thread '" + t.getName() + "': " + e.getMessage());
}
}
};
// create thread factory
ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
// System.out.println("creating pooled thread");
final Thread thread = new Thread(r);
thread.setUncaughtExceptionHandler(exceptionHandler);
return thread;
}
};
// create Threadpool
ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE, threadFactory);
// create Runnable
Runnable runnable = new Runnable() {
@Override
public void run() {
// System.out.println("A runnable runs...");
throw new RuntimeException("Error in Runnable");
}
};
// create Callable
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// System.out.println("A callable runs...");
throw new Exception("Error in Callable");
}
};
// a) submitting Runnable to threadpool
threadPool.submit(runnable);
// b) submit Callable to threadpool
threadPool.submit(callable);
// c) create a thread for runnable manually
final Thread thread_r = new Thread(runnable, "manually-created-thread");
thread_r.setUncaughtExceptionHandler(exceptionHandler);
thread_r.start();
threadPool.shutdown();
System.out.println("Done.");
}
}
我希望:消息未捕获异常的三倍。 ..
I expect: Three times the message "Uncaught exception..."
我得到:消息一次(由手动创建的线程触发)。
I get: The message once (triggered by the manually created thread).
在Windows 7和Mac OS X 10.5上使用Java 1.6重现。
Reproduced with Java 1.6 on Windows 7 and Mac OS X 10.5.
推荐答案
因为异常没有被删除。
你的ThreadFactory生成的线程没有直接给你的Runnable或Callable。相反,您获得的Runnable是一个内部Worker类,例如,请参阅ThreadPoolExecutor $ Worker。在示例中给出newThread的Runnable上尝试 System.out.println()
。
The Thread that your ThreadFactory produces is not given your Runnable or Callable directly. Instead, the Runnable that you get is an internal Worker class, for example see ThreadPoolExecutor$Worker. Try System.out.println()
on the Runnable given to newThread in your example.
此工作者捕获任何来自提交作业的RuntimeExceptions。
This Worker catches any RuntimeExceptions from your submitted job.
您可以在 ThreadPoolExecutor #afterExecute 方法。
这篇关于为什么ExecutorService不调用UncaughtExceptionHandler?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!