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,也不会调用。所以确保计划任务不会抛出未捕获的异常。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?