reentrantreadwritelock将aqs的32位state高16位存读锁计数、低16位存写锁重入次数;读锁共享并发(仅需写锁空闲),写锁独占互斥(需读写均空闲或重入),所有操作通过cas原子更新。

Java 中的 ReadWriteLock(如 ReentrantReadWriteLock)底层基于 AQS(AbstractQueuedSynchronizer)实现,其核心在于**复用 AQS 的一个 int 类型 state 字段,将高 16 位用于表示读锁计数,低 16 位用于表示写锁重入次数**。这种位拆分设计实现了读写状态的紧凑共存与原子操作。
state 字段的位划分与语义
AQS 的 state 是一个 volatile int,ReentrantReadWriteLock 将其视为两个半整型(16-bit):
- 高 16 位(bits 16–31):记录当前持有读锁的线程总数(不是读线程个数,而是所有读线程的加锁总次数,支持重入)
- 低 16 位(bits 0–15):记录当前写锁的重入次数(仅当有线程持有写锁时非零;写锁是独占的,所以该值只属于一个线程)
例如:state = 0x0003_0005 表示:读锁被获取了 3 次(可能来自 1 个线程重入 3 次,或 3 个线程各 1 次),写锁被当前线程重入了 5 次。
读锁获取(共享模式)的关键逻辑
读锁使用 AQS 的 共享模式(acquireShared),需满足两个前提才可成功:
- 写锁未被占用(即
state & 0xFFFF == 0) - 当前线程不是已获取写锁的线程(避免写锁降级时死锁,但降级需显式支持)
获取时通过 CAS 原子增加高 16 位(如 state + (1 ),失败则进入 AQS 共享队列等待。AQS 会自动唤醒后续共享节点,实现“多个读线程并发通行”。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
写锁获取(独占模式)的关键逻辑
写锁走 AQS 的 独占模式(acquire),判断是否可获取的条件更严格:
- 整个
state == 0(无任何读锁、无任何写锁)→ 公平场景下可直接抢占 - 或当前线程已是写锁持有者(支持重入)→ 此时只需 CAS 增加低 16 位
一旦有读锁(高 16 位 > 0)或其它线程持有写锁(低 16 位 > 0 且非当前线程),写请求就会阻塞,直到 state 归零或重入条件满足。
锁释放与状态更新的原子性保障
所有状态变更(读锁加/减、写锁加/减)都依赖 compareAndSetState 或 unsafe.compareAndSwapInt,确保多线程下 state 修改的原子性。例如:
- 释放一次读锁:CAS 尝试将 state 减去
(1 - 释放一次写锁:CAS 尝试将 state 减去
1
若 CAS 失败(state 被其他线程修改),则重试,直到成功。AQS 的模板方法(如 tryReleaseShared / tryRelease)封装了这些位运算和校验逻辑,上层无需关心底层细节。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










