UncaughtExceptionHandler意外行为,然后冻结

时间:2013-09-27 20:41:23

标签: java multithreading executorservice uncaughtexceptionhandler

我的消费者没有像我期望的那样工作。以下是我的真实计划中发生的sscce

  • 预期:
    1. 打印In finally!
    2. 打印About to print stacktrace
    3. 打印NullPointerException堆栈跟踪。
  • 实际值:
    1. 打印In finally!
    2. sun.misc.Unsafe
    3. 中挂起

程序:

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

1 个答案:

答案 0 :(得分:2)

在Executor中运行的Runnables并没有真正抛出会触及线程未捕获异常处理程序的异常。相反,Runnable包含了捕获Throwable的代码。这样Future就可以返回从任务中抛出的异常。

正如@Gray在下面的评论中指出的那样,你的程序是“挂起”,因为线程池线程正在阻止程序退出。您的runnable已完成,并且线程池线程正在等待新任务。如果关闭线程池,程序将正常完成(或创建线程池线程守护程序)。