我的消费者没有按照我期望的方式工作。以下是 sscce我的真实程序中发生的情况。
- 预期:
- 打印
终于来了!
- 打印
关于打印堆栈跟踪
- 打印
NullPointerException
堆栈跟踪。
- 打印
- 实际:
- 打印
终于来了!
- 挂起,在
sun.misc.Unsafe
- 打印
程序:
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class ThreadTest implements Runnable {
public static void main(String... args) {
ExecutorService service = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread newThread = new Thread(r);
newThread.setUncaughtExceptionHandler(new MyExceptionHandler());
return newThread;
}
});
service.submit(new ThreadTest());
}
private static class MyExceptionHandler implements UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("About to print stacktrace");
e.printStackTrace();
}
}
@Override
public void run() {
Object foo = null;
try {
while(!Thread.interrupted()) {
Thread.sleep(1000);
System.out.println(foo.toString());
System.out.println("After npe!");
}
} catch(InterruptedException e) {
} finally {
System.out.println("In finally!");
}
}
}
最佳答案
在 Executor 内部运行的 Runnable 不会真正抛出异常,这会触发线程的未捕获异常处理程序。相反,Runnable 是用捕获 Throwable 的代码包装的。这样 Future 就可以返回从任务中抛出的异常。
正如 @Gray 在下面的评论中指出的那样,您的程序“挂起”,因为线程池线程阻止程序退出。您的可运行已完成,线程池线程正在等待新任务。如果关闭线程池,您的程序将正常完成(或使线程池线程守护进程)。
关于java - UncaughtExceptionHandler 行为异常,然后卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19059720/