面试官:线程池中线程异常后,销毁还是复用?

共 1719字,需浏览 4分钟

 ·

2024-06-17 14:11

分享两道比较有意思的线程池面试题,面试中问到至少有 80% 求职者回答不上来。

这两个问题也是经常被拿来考察求职者对于线程池的了解。

  1. 线程池中线程异常后,销毁还是复用?
  2. 线程池在提交任务前,可以提前创建线程吗?

线程池中线程异常后,销毁还是复用?

直接说结论,需要分两种情况:

  • 使用execute()提交任务:当任务通过execute()提交到线程池并在执行过程中抛出异常时,如果这个异常没有在任务内被捕获,那么该异常会导致当前线程终止,并且异常会被打印到控制台或日志文件中。线程池会检测到这种线程终止,并创建一个新线程来替换它,从而保持配置的线程数不变。
  • 使用submit()提交任务:对于通过submit()提交的任务,如果在任务执行中发生异常,这个异常不会直接打印出来。相反,异常会被封装在由submit()返回的Future对象中。当调用Future.get()方法时,可以捕获到一个ExecutionException。在这种情况下,线程不会因为异常而终止,它会继续存在于线程池中,准备执行后续的任务。

简单来说:使用execute()时,未捕获异常导致线程终止,线程池创建新线程替代;使用submit()时,异常被封装在Future中,线程继续复用。

这种设计允许submit()提供更灵活的错误处理机制,因为它允许调用者决定如何处理异常,而execute()则适用于那些不需要关注执行结果的场景。

具体的源码分析可以参考这篇:线程池中线程异常后:销毁还是复用?- 京东技术

线程池在提交任务前,可以提前创建线程吗?

答案是可以的!ThreadPoolExecutor 提供了两个方法帮助我们在提交任务之前,完成核心线程的创建,从而实现线程池预热的效果:

  • prestartCoreThread():启动一个线程,等待任务,如果已达到核心线程数,这个方法返回 false,否则返回 true;
  • prestartAllCoreThreads():启动所有的核心线程,并返回启动成功的核心线程数。

⭐️推荐:

点击下方卡片进入公众号

回复 「PDF 即可领取原创PDF技术面试手册
回复 「学习路线 即可获取最新版Java学习路线
回复 「开源 即可获取优质Java开源项目合集
免费分享无套路,有帮助点个赞就好!

浏览 897
4点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
4点赞
评论
收藏
分享

手机扫一扫分享

分享
举报