剖析 AQS 源码(一):独占锁的获取与释放
2023-12-20 15:13:02
导语:
AQS(AbstractQueuedSynchronizer)作为 Java 并发编程中的中流砥柱,其源码中蕴含着丰富的并发设计思想。本文将逐行分析 AQS 源码,从独占锁的获取与释放入手,带领读者深入探究 AQS 的工作原理。
1. 引言:
AQS 采用乐观锁机制,辅以自旋重试,实现了轻量级且高效的并发控制。其核心思想是维护一个共享变量(state),表示锁的状态。当线程尝试获取锁时,会通过 CAS 操作尝试修改 state 的值,若成功则获取锁,否则自旋重试。
2. 独占锁的获取:
在 AQS 中,独占锁的获取通过 acquire
方法实现。acquire
方法的核心步骤如下:
// Attempt to acquire the lock without blocking or acquiring interrrupt status
if (compareAndSetState(expect, acquireQueued)) {
// Acquisition is successful
return true;
}
首先,acquire
尝试通过 CAS 操作将 state
从 expect
值修改为 acquireQueued
值。如果 CAS 成功,则表明当前线程已获取锁,返回 true
。
3. 自旋重试:
如果 CAS 操作失败,则表明锁已被其他线程持有。此时,线程不会阻塞,而是自旋重试。自旋重试的代码如下:
// The acquired status value
final int acquired = getState(); // Returns acquireQueued
// Loop while acquiring or waiting to acquire
if (!tryAcquire(acquired) && acquireQueued == acquired)
selfInterrupt();
自旋重试的原理是,不断检查 state
的值,如果 state
的值发生了变化(表明锁已释放),则尝试再次获取锁。如果自旋重试一段时间后,锁仍未获取,则线程会被中断。
4. 释放锁:
独占锁的释放通过 release
方法实现。release
方法的核心步骤如下:
// Release the lock, setting state to unlocked if necessary
if (tryRelease(state)) {
return true;
}
release
方法首先尝试通过 tryRelease
方法释放锁。如果 tryRelease
成功,则表明锁已成功释放,返回 true
。
5. 总结:
通过分析 AQS 源码中的独占锁获取与释放过程,我们可以深入理解 AQS 的工作原理。AQS 巧妙地运用 CAS 操作和自旋重试机制,实现了一种高效且轻量级的并发控制方案。
6. SEO 优化: