面试官:线程池中线程异常后,销毁还是复用?
共 1719字,需浏览 4分钟
·
2024-06-17 14:11
分享两道比较有意思的线程池面试题,面试中问到至少有 80% 求职者回答不上来。
这两个问题也是经常被拿来考察求职者对于线程池的了解。
线程池中线程异常后,销毁还是复用?
线程池在提交任务前,可以提前创建线程吗?
线程池中线程异常后,销毁还是复用?
直接说结论,需要分两种情况:
使用execute()提交任务:当任务通过execute()提交到线程池并在执行过程中抛出异常时,如果这个异常没有在任务内被捕获,那么该异常会导致当前线程终止,并且异常会被打印到控制台或日志文件中。线程池会检测到这种线程终止,并创建一个新线程来替换它,从而保持配置的线程数不变。
使用submit()提交任务:对于通过submit()提交的任务,如果在任务执行中发生异常,这个异常不会直接打印出来。相反,异常会被封装在由submit()返回的Future对象中。当调用Future.get()方法时,可以捕获到一个ExecutionException。在这种情况下,线程不会因为异常而终止,它会继续存在于线程池中,准备执行后续的任务。
简单来说:使用execute()时,未捕获异常导致线程终止,线程池创建新线程替代;使用submit()时,异常被封装在Future中,线程继续复用。
这种设计允许submit()提供更灵活的错误处理机制,因为它允许调用者决定如何处理异常,而execute()则适用于那些不需要关注执行结果的场景。
具体的源码分析可以参考这篇:线程池中线程异常后:销毁还是复用?- 京东技术。
线程池在提交任务前,可以提前创建线程吗?
答案是可以的!ThreadPoolExecutor 提供了两个方法帮助我们在提交任务之前,完成核心线程的创建,从而实现线程池预热的效果:
prestartCoreThread():启动一个线程,等待任务,如果已达到核心线程数,这个方法返回 false,否则返回 true;
prestartAllCoreThreads():启动所有的核心线程,并返回启动成功的核心线程数。
⭐️推荐:
如何检测和避免线程死锁?
从 5s 到 0.5s!看看人家的 CompletableFuture 异步任务优化技巧,确实优雅!
为什么线程崩溃不会导致 JVM 崩溃?
Thread、Runnable、Callable、Future ... 的关系?
如果不允许线程池丢弃任务,应该选择哪个拒绝策略?
如何设计一个优先级任务线程池?
手写一个轻量级动态线程池,很香!!
8 个线程池最佳实践和坑!使用不当直接生产事故!!
ConcurrentHashMap 为何不能插入 null?HashMap 为何可以?
点击下方卡片进入公众号
回复 「PDF」 即可领取原创PDF技术面试手册
回复 「学习路线」 即可获取最新版Java学习路线
回复 「开源」 即可获取优质Java开源项目合集
免费分享无套路,有帮助点个赞就好!
评论
