线程池死锁问题

发布时间:2026/11/6 5:25:16
线程池死锁问题 一、execute /submit 代码示例1. execute无返回值异常直接打印日志public class ThreadPoolDemo { public static void main(String[] args) { ExecutorService pool Executors.newFixedThreadPool(2); // execute不需要返回结果 pool.execute(() - { System.out.println(execute任务执行); int num 1 / 0; // 抛出算术异常 }); } }现象任务抛异常自动打印异常堆栈日志worker 线程销毁重建。2. submit需要返回值异常存在 Futureget 才抛public class ThreadPoolDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService pool Executors.newFixedThreadPool(2); FutureInteger future pool.submit(() - { System.out.println(submit任务执行); int num 1 / 0; return 100; }); // 不调用get没有任何报错、日志异常被吞 // future.get(); // 执行get这一行才抛出ExecutionException } }结论要拿结果就用 submit不调用 get异常静默丢失。二、线程池【线程饥饿死锁】完整代码示例场景newFixedThreadPool(5)固定 5 条线程外层异步任务内部再次往同一个池子 submit 内层任务然后 get 阻塞import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class ThreadPoolDeadLockDemo { // 同一个线程池总共5个线程不能扩容 private static final ExecutorService pool Executors.newFixedThreadPool(5); public static void main(String[] args) { // 提交5个【外层大任务】刚好占满5条worker线程 for (int i 0; i 5; i) { pool.submit(() - { System.out.println(外层任务开始执行 Thread.currentThread().getName()); try { // 在外层异步任务内部继续往同一个线程池提交【内层小任务】 FutureString innerFuture pool.submit(() - { System.out.println(内层任务运行 Thread.currentThread().getName()); return 内层任务执行完成; }); // 重点阻塞等待内层任务结果 String result innerFuture.get(); System.out.println(拿到内层结果 result); } catch (Exception e) { e.printStackTrace(); } System.out.println(外层任务执行结束); }); } } }代码运行逻辑拆解循环提交 5 个外层任务5 条线程全部被外层任务占用每个外层任务执行到pool.submit(内层任务)内层任务放入队列排队执行innerFuture.get()外层 worker 线程阻塞外层任务没跑完线程不会释放归还池子因为get需要再开启一个线程。现在 5 个 worker 全部卡在 get队列里面放了 5 个内层任务newFixedThreadPool没有非核心线程队列没满不会新建线程没有空闲线程去拿队列里的内层任务 → 内层任务永远跑不完 → get 永久阻塞全部卡死线程饥饿死锁。解决方案代码示例方案 1分开两个线程池// 外层任务池 private static final ExecutorService outerPool Executors.newFixedThreadPool(5); // 内层任务池独立线程互不抢占 private static final ExecutorService innerPool Executors.newFixedThreadPool(5); public static void main(String[] args) { for (int i 0; i 5; i) { outerPool.submit(() - { try { // 内层任务提交到另一个池子 FutureString innerFuture innerPool.submit(() - 内层完成); String res innerFuture.get(); } catch (Exception e) { e.printStackTrace(); } }); } }面试背诵总结execute不需要返回结果任务异常直接打印堆栈日志。submit需要获取返回结果异常保存在 Future 对象调用 get 时才抛出包装异常不调用 get 异常会静默丢失。死锁场景同一个线程池异步任务内部再次提交新任务并且调用 get 阻塞等待。线程全部被外层任务占住、阻塞不释放队列内层任务无线程执行发生线程饥饿死锁。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询