java - UncaughtExceptionHandler 行为异常,然后卡住

标签 java multithreading executorservice uncaughtexceptionhandler

我的消费者没有按照我期望的方式工作。以下是 sscce我的真实程序中发生的情况。

  • 预期:
    1. 打印终于来了!
    2. 打印关于打印堆栈跟踪
    3. 打印 NullPointerException 堆栈跟踪。
  • 实际:
    1. 打印终于来了!
    2. 挂起,在 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/

相关文章:

java - 如果任何包占用大量时间,则使线程超时

java - java中可调用的空指针异常

java - MVC 和 Java-EE

java - 如何在supercsv getHeader中使用编码

java - 从 Java 发送字节时 Arduino 崩溃

java - 以同步、线程安全的方式加载共享资源

java - 重用可调用实例似乎可行。这可以吗?

Java - 同步线程 - 输出顺序错误

c++ - 线程不会在 Linux 上终止,但会在 Mac 上终止

java - ExecutorService:如何检查我的 Callable 是否正在执行?