Last updated on 2025-11-23T21:13:17+08:00
1. TODO
2. 脑图
Xmind
Edraw
Hexo 地址
👉 http://blog.wangjia.ink/2025/11/09/源码:java.util.concurrent.locks.ReentrantReadWriteLock源码解析/
3. 基础部分
3.1. ReentrantReadWriteLock 概述
ReentrantReadWriteLock 是一个具体类,实现了 java.util.concurrent.locks.ReadWriteLock、java.io.Serializable

ReentrantReadWriteLock 是一种可重入、悲观、公平或非公平、互斥或共享的锁,并且是使用 AQS 实现的混合模式的同步器。State 和共享资源分别表示以下含义:
State 表示写锁或读锁的重入次数
State 被 ReentrantReadWriteLock 拆分为两部分,分别表示写锁和读锁的重入次数
- 低
16 位表示写锁的重入次数
- 高
16 位表示读锁的重入次数
- 需要注意的是:如果为
0,表示锁空闲,既没有写锁,也没有读锁
- 共享资源表示加锁期间的操作
我们可以简单的理解为:ReentrantReadWriteLock 为我们准备了两把锁,一把是读锁,一把是写锁,我们就是依赖这两把锁进行协调,这两把锁遵循这样的规律:
- 写写互斥
- 当一个线程持有写锁后,其他线程如果要竞争写锁,必须等待该线程释放写锁
- 读写互斥
- 当一个线程持有写锁后,其他线程如果要竞争读锁,必须等待该线程释放写锁
- 当一个线程持有读锁后,其他线程如果要竞争写锁,必须等待该线程释放读锁
- 读读共享
- 当一个线程持有读锁后,其他线程如果要竞争读锁,可以直接持有读锁
- 也就是说:一个读锁可以被多个线程共享
[!NOTE] 注意事项
- 详见源码:
ReadWriteLock
obsidian 内部链接:
- 源码:java.util.concurrent.locks.ReadWriteLock源码解析
Hexo 链接:
- http://blog.wangjia.ink/2025/11/07/源码:java.util.concurrent.locks.ReadWriteLock源码解析/
- 详见源码:
Serializable
obsidian 内部链接:
- 源码:java.io.Serializable源码解析
Hexo 链接:
- http://blog.wangjia.ink/2025/10/28/源码:java.io.Serializable源码解析/
3.2. ReentrantReadWriteLock 锁降级
ReentrantLock 允许一个线程在持有写锁的情况下竞争读锁,竞争到读锁后再释放写锁。
[!NOTE] 注意事项
- 猴哥的烦恼箱
(。•́︿•̀。)
- 为什么不先释放写锁,再竞争读锁?
- 如果线程
A 写数据后,需要立刻读数据
- 如果先释放写锁,再竞争读锁,那么线程
A 释放写锁后,线程 B 可能立即竞争到了写锁
- 如果线程
B 也写了数据,则当线程 A 再竞争到读锁的时候,读到的数据就不是刚刚写的数据了
- 为什么不干脆 “不释放写锁”,直到读完数据?
- 可以这样做,但是性能差,而我们的目标是:在保证数据一致性的前提下,尽可能地提升并发度
3.3. ReentrantReadWriteLock 适用场景
3.3.1. 读多写少
4. 内部类
4.1. Sync
4.2. FairSync
1 2 3 4 5 6 7 8 9 10 11 12 13
| static final class FairSync extends Sync {
private static final long serialVersionUID = -2274990926593161451L; final boolean writerShouldBlock() { return hasQueuedPredecessors(); } final boolean readerShouldBlock() { return hasQueuedPredecessors(); } }
|
4.3. NonfairSync
1 2 3 4 5 6 7 8 9 10 11
| static final class NonfairSync extends Sync { final boolean writerShouldBlock() { return false; } final boolean readerShouldBlock() { return apparentlyFirstQueuedIsExclusive(); } }
|
4.4. ReadLock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public static class ReadLock implements Lock, java.io.Serializable { private final Sync sync; protected ReadLock(ReentrantReadWriteLock lock) { sync = lock.sync; } public void lock() { sync.acquireShared(1); } public void lockInterruptibly() throws InterruptedException { sync.acquireSharedInterruptibly(1); } public boolean tryLock() { return sync.tryReadLock(); } public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); } public void unlock() { sync.releaseShared(1); } public Condition newCondition() { throw new UnsupportedOperationException(); } public String toString() { int r = sync.getReadLockCount(); return super.toString() + "[Read locks = " + r + "]"; } }
|
4.5. WriteLock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public static class WriteLock implements Lock, java.io.Serializable { private final Sync sync; protected WriteLock(ReentrantReadWriteLock lock) { sync = lock.sync; } public void lock() { sync.acquire(1); } public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } public boolean tryLock() { return sync.tryWriteLock(); } public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } public void unlock() { sync.release(1); } public Condition newCondition() { return sync.newCondition(); } public String toString() { Thread o = sync.getOwner(); return super.toString() + ((o == null) ? "[Unlocked]" : "[Locked by thread " + o.getName() + "]"); } public boolean isHeldByCurrentThread() { return sync.isHeldExclusively(); } public int getHoldCount() { return sync.getWriteHoldCount(); } }
|
5. 实例方法
5.1. 实例具体方法
5.1.1. 具体方法(实现)
5.1.1.1. ReadWriteLock 中接口方法的实现
5.1.1.1.1. WriteLock writeLock()
1 2 3 4 5
| public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
|
5.1.1.1.2. ReadLock readLock()
1 2 3 4 5
| public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
|