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 @   ppjj  阅读(2067)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示