现象

线上服务日志发现有中断(即日志前面有打印, 但后面的日志没打印), 并且又没有异常信息输出.

原因

代码示例

    private static final ThreadPoolTaskExecutor THREAD_POOL_TASK_EXECUTOR = new ThreadPoolTaskExecutor();

    static {
        THREAD_POOL_TASK_EXECUTOR.setQueueCapacity(10000);
        THREAD_POOL_TASK_EXECUTOR.setDaemon(true);
        THREAD_POOL_TASK_EXECUTOR.setThreadNamePrefix("global-%d");
        THREAD_POOL_TASK_EXECUTOR.setRejectedExecutionHandler((r, executor) -> {
            Loggers.ERROR_LOG.info("加入任务被拒绝: {}", r);
            //自动执行
            r.run();
        });
        THREAD_POOL_TASK_EXECUTOR.setThreadFactory(r -> {
            final Thread thread = new Thread(r);
            thread.setUncaughtExceptionHandler((t, e) -> Loggers.ERROR_LOG.error(e.getMessage(), e));
            return thread;
        });
        THREAD_POOL_TASK_EXECUTOR.setWaitForTasksToCompleteOnShutdown(true);
        THREAD_POOL_TASK_EXECUTOR.initialize();
    }

    @PreDestroy
    public void destroy() {
        THREAD_POOL_TASK_EXECUTOR.shutdown();
    }

    public void submit(Runnable task) {
        THREAD_POOL_TASK_EXECUTOR.submit(task);
    }

原来是 ThreadPoolTaskExecutor.submit 方法, 这个方法的返回值是 Future 类型. 默认情况下, 它只有在调用 get() 方法时才会返回处理结果以及异常检查.

处理

  1. 调用 get() 方法. 但这里显然不太符合我们的要求. 我们是想它异步处理的, 并不需要等待它的结果.

  2. submit() 修改为 execute()

参考资料

https://www.jianshu.com/p/d7d0a32cf028