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

Scala Future死锁成因解析:Await.result为何引发死锁?

为什么这段Scala代码会触发死锁?

你的猜测完全正确!咱们一步步拆解这个死锁的形成过程,就能把逻辑理得明明白白:

首先看线程池的核心配置:这里用Executors.newFixedThreadPool(1)创建了仅含1个工作线程的线程池,所有Future任务的执行都依赖这唯一的线程。

接下来看具体执行流程:

  • 当调用multiply方法时,外层的Future { ... }会把它的代码块提交到这个单线程池,此时线程池的唯一线程开始执行这个multiply任务。
  • 在multiply的任务里,我们调用了addOne(x)和addOne(y),这两个方法各自生成了一个新的Future,它们会被放入线程池的任务队列中,等待空闲线程来执行。
  • 随后的for推导式result是一个组合Future,它要等a和b这两个Future都执行完成后,才能计算出最终的乘积结果。
  • 最关键的一步来了:Await.result(result, Duration.Inf)会让当前正在执行multiply任务的线程阻塞挂起,直到result完成。但此时线程池里唯一的线程正被这个阻塞的multiply任务占用着,队列里的addOne任务根本没有机会被执行——因为没有其他线程能处理它们!

这就形成了典型的循环等待死锁:

  • multiply的线程在等result完成,而result依赖a和b的执行结果;
  • a和b的任务在等线程池的空闲线程,但唯一的线程被multiply的阻塞操作占着,永远不会释放。

如果把线程池的大小改成2,这个死锁就不会发生:当multiply的线程阻塞时,另一个空闲线程可以去执行addOne的任务,result就能正常完成,Await.result也能拿到结果。

内容的提问来源于stack exchange,提问作者WeiChing 林煒清

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:28:45