在 Java 并发编程的世界里,ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock、ThreadPoolExecutor 的 Worker……这些我们几乎每天都在使用的工具,背后都站着一个共同的"地基"——AbstractQueuedSynchronizer(AQS)。它是 java.util.concurrent(JUC)包中最核心的抽象,没有之一。
2023/4/8大约 11 分钟
在 Java 并发编程的世界里,ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock、ThreadPoolExecutor 的 Worker……这些我们几乎每天都在使用的工具,背后都站着一个共同的"地基"——AbstractQueuedSynchronizer(AQS)。它是 java.util.concurrent(JUC)包中最核心的抽象,没有之一。
Java 的并发编程里,synchronized 与 ReentrantLock 是两座绕不开的大山。很多人背得下"前者是隐式锁、后者是显式锁"的八股,却说不清它们背后到底发生了什么:偏向锁为什么在 JDK 15 被废弃?AQS 的 CLH 队列为什么并不真的是 CLH?非公平锁比公平锁快,快的到底是谁、快在哪一步?本文不重复手册,而是从字节码、对象头、AQS 源码和生产事故四个层面,把这两把锁的底层机制与优化路径讲透。
synchronized 是 JVM 层面的语言内建机制,加锁与解锁由编译器和 JVM 协同完成,程序员拿不到锁对象。它在字节码层面表现为一对指令:monitorenter 与 monitorexit。