返回

剖析 AQS 源码(一):独占锁的获取与释放

后端

导语:

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 操作将 stateexpect 值修改为 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 优化: