为什么ExecutorService不调用UncaughtExceptionHandler? [英] Why is UncaughtExceptionHandler not called by ExecutorService?

查看:187
本文介绍了为什么ExecutorService不调用UncaughtExceptionHandler?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我偶然发现了一个问题,可以总结如下:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆