跳到主要内容
约 3 分钟2 张卡

死锁

死锁是执行主体相互等待资源,导致无法继续的状态。本文负责死锁条件、预防、避免和恢复。

1. 面试核心​

先记住这几条,再读正文
  • 必要条件。 经典死锁需要互斥、占有并等待、不可剥夺和循环等待四个条件同时成立。预防死锁可以从破坏其中一个条件入手。
  • 固定加锁顺序。 按统一顺序获取资源可破坏循环等待。卡 · 面试核心
  • 安全状态。 银行家算法检查资源分配后是否仍存在安全序列。卡 · 预防与恢复
  • 超时恢复。 锁等待超时结束一次等待,原持有资源由失败路径释放。

2. 等待环​

线程 T1:持有 A,等待 B
线程 T2:持有 B,等待 A

A、B 各只能由一个线程持有。两个线程都等到获得另一把锁才释放原锁。它们形成 T1 → T2 → T1 的等待环。

必要条件含义
互斥同一资源实例不能同时分配给多个主体。
占有并等待持有资源时继续等待其他资源。
不可剥夺资源由持有者主动释放。
循环等待每个主体等待环中下一个主体持有的资源。

每类资源仅有一个实例时,等待图中的环意味着死锁。多实例资源图中的环则只提示死锁风险。其他实例的释放仍能解除等待。

3. 预防与恢复​

预防通过破坏必要条件阻止死锁。例如所有线程都先获取 A,再获取 B。多个业务对象应按稳定键排序后加锁。

一次性取得所需资源可破坏占有并等待。尝试获取失败时,应释放已有资源再重试。该方案会增加等待或资源闲置。

检测机制收集等待关系,判断是否存在死锁。恢复可中止任务或回滚操作,再释放资源。强制停止持锁线程前,必须能恢复共享状态。

4. 安全状态与死锁避免​

安全状态存在一种任务完成顺序。系统按该顺序分配资源,所有任务都能完成。银行家算法在批准新请求前检查这一条件。

假设共 10 份同类资源。P1 已有 5 份,最多需要 7 份。P2 已有 3 份,最多需要 9 份。剩余 2 份可以先给 P1。P1 完成后释放 7 份,足够 P2 完成。

若先把剩余 2 份给 P2,就没有可用资源。两者都无法获得声明的剩余最大需求。该分配会进入不安全状态,应被拒绝。

不安全状态表示缺少保证完成的安全序列。若实际需求低于声明上限,任务仍能结束。因此不安全状态与已经死锁需分别判断。

银行家算法依赖事先已知的最大需求。通用服务难以准确预报需求,锁顺序更易落地。

5. 使用边界​

长等待也会来自慢 I/O 或资源不足。诊断时需要线程栈、持有者和完整等待链。

活锁中线程持续运行,却因相互干扰而缺少进展。饥饿则是某个任务长期得不到资源。退避和随机抖动可减少重试碰撞。公平排队可改善饥饿。

锁超时后只重试当前调用,会保留原有等待条件。失败路径应释放资源,再开启新的尝试。

6 · 面试题卡片​

先想答案,再翻面先在心里答一遍,再点开卡片对照参考回答。卡片之间可以左右切换,看完会回到这里。
逐张翻看 2 张 →
未标记的卡读完后明天进入复习;已标记的按状态安排
本页题目与参考回答

6.1 死锁需要哪些条件,如何避免两个线程反向获取锁造成的死锁?​

考察重点:经典死锁条件、等待环与统一加锁顺序的作用。

相关内容:面试核心、等待环、使用边界。

参考回答

经典死锁需要四个条件同时成立。

它们是互斥、占有并等待、不可剥夺和循环等待。让所有线程按统一顺序获取 A、B,可打破循环等待。使用超时时,还需释放已持有资源并恢复中间状态。

6.2 死锁预防和避免有什么区别,不安全状态就是死锁吗?​

考察重点:必要条件、安全序列与需求上限。

相关内容:预防与恢复、安全状态与死锁避免。

参考回答

预防通过规则破坏某个必要条件。

避免则在每次分配时检查安全状态。银行家算法依赖任务声明的最大资源需求。不安全状态缺少安全完成保证,但实际需求更小时仍可结束。

7. 参考资料​