gpt4 book ai didi

java - 为什么ExecutorService不调用UncaughtExceptionHandler?

转载 作者:IT老高 更新时间:2023-10-28 20:26:39 46 4
gpt4 key购买 nike

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

当我手动创建线程(即通过实例化 java.lang.Thread)时,会适本地调用 UncaughtExceptionHandler。但是,当我将 ExecutorServiceThreadFactory 一起使用时,将省略处理程序。我错过了什么?

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.");
}
}

我期望:消息“未捕获的异常...”的三倍

我得到:消息一次(由手动创建的线程触发)。

在 Windows 7 和 Mac OS X 10.5 上使用 Java 1.6 复制。

最佳答案

因为异常不会被捕获。

您的 ThreadFactory 生成的 Thread 没有直接给您 Runnable 或 Callable。相反,您获得的 Runnable 是一个内部 Worker 类,例如参见 ThreadPoolExecutor$Worker。在示例中为 newThread 提供的 Runnable 上尝试 System.out.println()

此 Worker 从您提交的作业中捕获任何 RuntimeExceptions。

您可以在 ThreadPoolExecutor#afterExecute 中获得异常。方法。

关于java - 为什么ExecutorService不调用UncaughtExceptionHandler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1838923/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com