java中ThreadExecutor使用注意事项

(一)、示例:

public class ThreadPoolDemo3 {

    public static void main(String[] args) {

        ExecutorService executorService = Executors.newFixedThreadPool(4);

        for (int i = 0; i < 5; i++) {
            int index = i;
            executorService.submit(() -> divTask(100, index));


        }
        executorService.shutdown();
    }

    private static void divTask(int a, int b) {
        double result = a / b;
        System.out.println(result);
    }
}

运行结果:

 

 上述代码,可以看出运行结果为4个,因该是有5个的,但是当i=0的时候,100/0是会报错的,但是日志信息中没有任何信息,是为什么那?如果使用了submit(Runnable task) 就会出现这种情况,任何的错误信息都出现不了!

这是因为使用submit(Runnable task) 的时候,错误的堆栈信息跑出来的时候会被内部捕获到,所以打印不出来具体的信息让我们查看,而且也没有返回值,解决的方法有如下两种:

1、使用execute()代替submit()

使用结果:

 

2、使用Future,实现Callable接口,它会转换成Runnable实例,并返回,这样就可以获取线程执行结果,也可能返回异常结果:

使用结果:

 

 

(二)、由于线程池在执行过程中会因为异常终止,尽管ThreadPoolExecutor会侦测这种情况,并在工作线程终止时候启动新的线程,但是由于线程创建和启动有开销,我们尽量避免未捕获的异常,可以通过setThreadFactory,为线程池关联一个线程工厂,在工厂里为每一个线程设置UncaughtExceptionHandler,不过只有执行ThreadPoolExecutor.execute调用的任务所抛出的异常才会导致UncaughtExceptionHandler调用,而调用ThreadPoolExecutor.submit不会调用UncaughtExceptionHandler。

(三)、提交给ScheduledExecutorService执行的计划任务在其执行过程中如果抛出未捕获的异常,那么该任务不会再执行,即使线程工厂为其关联一个UncaughtExceptionHandler,也不会调用。所以确保计划任务不会抛出未捕获的异常。

posted @ 2018-08-03 11:46  ppjj  阅读(2048)  评论(0编辑  收藏  举报