死锁的发生需要满足哪四个必要条件?为什么在设计中破坏其中任意一个条件就能预防死锁?
Which four necessary conditions must hold for a deadlock to occur, and why does breaking any single one of them in a design prevent deadlock?
死锁需要同时满足互斥、持有并等待、不可抢占和循环等待四个条件,缺一不可,因此它们是一组逻辑“与”关系。由此,一次性申请全部所需资源可以打破持有并等待;为资源统一编号并规定只能按升序申请可以消除循环等待;允许系统强制剥夺已持有的资源则否定了不可抢占。只要任何一个条件无法成立,环形等待链就永远无法闭合,死锁也就不会发生。
A deadlock requires mutual exclusion, hold-and-wait, no preemption, and circular wait to hold simultaneously — they form a logical conjunction, and all four are necessary. Exploiting that structure, requesting every needed resource up front breaks hold-and-wait; numbering resources and granting them only in ascending order eliminates circular wait; letting the system forcibly reclaim held resources negates no preemption. Once any single condition cannot hold, the waiting cycle can never close and deadlock becomes impossible.
难度 进阶 · 适合 大众
CC BY 4.0 · 已核验 · Verified 2026-11-04
来源 · Source
Coffman, Elphick & Shoshani,《System Deadlocks》,ACM Computing Surveys,1971 (DOI: 10.1145/356586.356588)
Coffman, Elphick & Shoshani, 'System Deadlocks', ACM Computing Surveys, 1971, DOI: 10.1145/356586.356588
独立核验依据 · Independent verification: 核验依据 1 Crossref DOI 10.1145/356586.356588
#并发编程 #死锁 #资源分配 #同步机制
两个线程各自更新互不相关的变量,放到多核上运行反而比单线程更慢——这就是“伪共享”(false sharing)。它在硬件层面的成因是什么?又该如何消除?
Two threads each update unrelated variables, yet on multicore hardware the result is slower than single-threaded execution—this is false sharing. What causes it at the hardware level, and how is it eliminated?
CPU 缓存一致性以整行为单位生效(常见 64 字节):两个逻辑独立的变量若恰落在同一缓存行,任一核心写入都会令其他核心缓存中的这行失效,行在核心间反复失效重载;程序本身并无共享数据,硬件却在持续同步这一行。对策是将各线程热点数据填充对齐到缓存行边界,如 C++ 的 alignas 与 JVM @Contended。
CPU cache coherence operates on whole cache lines (commonly 64 bytes): if two logically independent variables land on the same line, a write from any core invalidates that line in every other core's cache, so the line keeps bouncing between cores through invalidations and reloads. Nothing is genuinely shared, yet the hardware continuously synchronizes it. The remedy is padding and aligning each thread's hot data to cache-line boundaries, such as C++ alignas or the JVM @Contended annotation.
难度 进阶 · 适合 初中(12-15)
CC BY 4.0 · 已核验 · Verified 2026-11-02
来源 · Source
J. Torrellas、C. Tucker、A. Gupta,《False Sharing and Spatial Locality in Multiprocessor Caches》,IEEE Transactions on Computers,第43卷第6期,1994年,第651–663页
J. Torrellas, C. Tucker, A. Gupta, False Sharing and Spatial Locality in Multiprocessor Caches, IEEE Transactions on Computers, vol. 43, no. 6, 1994, pp. 651-663.
独立核验依据 · Independent verification: 核验依据 1 CROSSREF 标识 10.1109/12.286299:False sharing and spatial
#伪共享 #缓存一致性 #多线程
双重检查锁定(double-checked locking)单例在 Java 中为什么必须把实例字段声明为 volatile?不加会出什么问题?
Why must the instance field be declared volatile for the double-checked locking singleton in Java, and what goes wrong without it?
问题出在指令重排序:某线程执行 new 时,可能先分配内存、把引用写入字段,再执行构造器。另一线程首次检查读到非空引用,便使用尚未构造完成的对象。volatile 禁止这种重排序,并在字段写入与后续读之间建立 happens-before 关系,使读到非空引用的线程总能看到完整构造的对象。
The hazard is instruction reordering: a thread executing new may allocate memory and store the reference into the field before running the constructor. Another thread's first check then sees a non-null reference and uses a half-built object. volatile forbids that reordering and creates a happens-before edge between the field write and later reads, so any thread observing non-null always sees a fully constructed object.
难度 进阶 · 适合 大众
CC BY 4.0 · 已核验 · Verified 2026-11-03
来源 · Source
J. Bloch《Effective Java(Java 编程进阶)》英文第3版 Item 83(Addison-Wesley, 2018)
J. Bloch, Effective Java, 3rd ed., Item 83 (Addison-Wesley, 2018)
独立核验依据 · Independent verification: 核验依据 1 OPENLIBRARY 标识 /works/OL6223299W:Effective Java(首版 2001)
#并发编程 #双重检查锁定 #volatile #happens-before