BD *_*ill 7 java junit multithreading
我有以下代码,我希望成功运行完成,但代码失败的行"失败("不应该达到");".有人可以解释为什么不调用默认的未捕获异常处理程序:
public class UncaughtExceptionTest extends TestCase
    implements UncaughtExceptionHandler {
    private final List<Throwable> uncaughtExceptions =
        new CopyOnWriteArrayList<Throwable>();
    class UncaughtExceptionTestInnerClass implements Runnable {
        private final ScheduledThreadPoolExecutor executor =
            new ScheduledThreadPoolExecutor(1);
        private final CountDownLatch latch;
        UncaughtExceptionTestInnerClass(CountDownLatch latch) {
            this.latch = latch;
            executor.schedule(this, 50, TimeUnit.MILLISECONDS);
        }
        @Override
        public void run() {
            System.out.println("This is printed");
            fail("this should fail");
            latch.countDown();
        }
    }
    @Test
    public void testUncaughtExceptions() {
        Thread.setDefaultUncaughtExceptionHandler(this);
        CountDownLatch latch = new CountDownLatch(1);
        UncaughtExceptionTestInnerClass testTheInnerClass =
                new UncaughtExceptionTestInnerClass(latch);
        try {
            if (!latch.await(1, TimeUnit.SECONDS)) {
                if (uncaughtExceptions.size() > 0) {
                    Throwable exception = uncaughtExceptions.get(0);
                    System.out.println("First uncaught exception: " + 
                                    exception.getMessage());
                }
                else {
                    fail("this should not be reached");
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        uncaughtExceptions.add(e);
    }
}
sjl*_*lee 12
它与您使用Executor运行任务的事实有关.仅当线程由于未捕获的异常而被终止时,才会调用未捕获的异常处理程序.如果您将实现更改为使用普通线程,以便线程将以异常终止,您将看到预期的行为.
根据您提交任务的方式,执行程序线程可能会捕获所有Throwable并处理它们.因此,线程不会因为这些异常而终止,因此未捕获的异常处理程序不会涉及.例如,ThreadPoolExecutor.execute(Runnable)将触发未捕获的异常处理程序.但是,ThreadPoolExecutor.submit(Callable)没有.此外,ScheduledThreadPoolExecutor.schedule()也没有(它与他们使用FutureTask进行实现有关).
使用执行程序服务访问意外异常的更好方法是通过Future.