线程池吞并异常信息处理

255 阅读1分钟

示例

public class ThreadPoolExceptionApp {


    /**
     * 线程数量
     */
    private static final int THREAD_COUNT = 5;
    /**
     * 队列容量
     */
    private static final int QUEUE_CAPACITY = 1000;

    public static void main(String[] args) {
        //创建线程池
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(QUEUE_CAPACITY);
        ThreadFactory factory = r -> new Thread(r, "test-thread-pool");
        //拒绝策略交由调用线程处理
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(THREAD_COUNT, THREAD_COUNT, 0L,
                TimeUnit.SECONDS, queue, factory, new ThreadPoolExecutor.CallerRunsPolicy());
        try {
            threadPoolExecutor.execute(() -> {
                 int i = 0;
                 int b = 10 / i;
            });
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }

    }
}

上面的代码中,try语句块无法捕捉里面抛出来的异常信息。线程池里面的子线程会吞并异常信息,想在代码中捕获异常信息进行处理的话可以修改为下面两种方式:

1. 将try语句放在子线程中进行异常捕获。

threadPoolExecutor.execute(() -> {
    try {
        int i = 0;
        int b = 10 / i;
    } catch (Exception e) {
        System.out.println( "------" + e.getLocalizedMessage());
    }

});

2. 使用feature

try {
    Future<?> submit = threadPoolExecutor.submit(() -> {
        int i = 0;
        int b = 10 / i;
    });
    submit.get();
} catch (Exception e) {
    System.out.println(e.getLocalizedMessage());
}

feature中能够自动捕获异常,然后抛出来。这样就可以在外层父线程中捕获异常了。