You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Java线程池调用Future#get方法后程序无异常挂起问题求解

问题原因分析
  • 你定义的线程池参数是问题的核心诱因:核心线程数1、最大线程数1、工作队列使用SynchronousQueue、拒绝策略配置为DiscardPolicy。
  • 提交第一个任务taskOne时,核心线程处于空闲状态,直接分配核心线程执行taskOne,taskOne会休眠5秒,此时核心线程被完全占用。
  • 提交第二个任务taskTwo时的处理流程:
    1. 核心线程已占满,尝试将任务放入工作队列
    2. SynchronousQueue本身不存储任何任务,必须有空闲线程同步接收任务才能入队成功,此时没有空闲线程,入队直接失败
    3. 最大线程数已达到上限1,无法创建新的非核心线程执行任务
    4. 触发DiscardPolicy拒绝策略:该策略会直接静默丢弃被拒绝的任务,不会抛出任何异常,也不会给调用方任何通知
  • taskOne执行完成后,taskOne.get()正常返回null,因此第一行日志task one ,result: null正常打印。
  • 后续执行taskTwo.get()时,由于taskTwo已经被丢弃,对应的Future对象永远不会进入完成状态,无超时参数的get()方法会一直阻塞等待,因此程序直接挂起,不会抛出任何异常。
修复建议
  • 方案1:更换拒绝策略,比如改用默认的AbortPolicy,任务被拒绝时会直接抛出RejectedExecutionException,可以快速感知到任务被拒绝的问题
  • 方案2:调用get方法时指定超时时间,例如taskTwo.get(10, TimeUnit.SECONDS),避免程序无限期阻塞
  • 方案3:如果业务允许任务排队等待,更换为容量合适的阻塞队列(比如ArrayBlockingQueue),让第二个任务可以进入队列等待核心线程空闲后执行

内容的提问来源于stack exchange,提问作者rookie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:27:06