ReentrantReadWriteLock适用于读多写少场景,提供读锁共享、写锁独占机制。1. 读锁允许多线程并发读,写锁保证排他性;2. 支持重入,同一线程可多次获取对应锁;3. 写锁可降级为读锁,读锁不能升级;4. 加锁后必须释放,建议finally中unlock;5. 可选公平模式(防饥饿)或非公平模式(高性能,默认)。正确使用可显著提升并发性能。

在Java中,ReentrantReadWriteLock 是一种高效的同步工具,适用于读多写少的场景。它允许同时多个线程进行读操作,但写操作是独占的,保证了数据的一致性。下面介绍其核心使用方法和常见操作。
读锁与写锁的基本原理
ReentrantReadWriteLock 维护了一对锁:一个用于只读操作的读锁,一个用于写入操作的写锁。
- 读锁可以被多个线程共享,只要没有线程持有写锁。
- 写锁是独占的,一旦某个线程获取了写锁,其他所有读、写线程都会被阻塞。
- 该锁支持重入,即同一个线程可以多次获取读锁或写锁(需对应释放)。
基本使用示例
以下是一个简单的使用示例,展示如何通过读写锁保护共享资源:
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class SharedData {
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
private final ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
private int data = 0;
// 读操作
public int read() {
readLock.lock();
try {
System.out.println("读取数据: " + data);
return data;
} finally {
readLock.unlock();
}
}
// 写操作
public void write(int value) {
writeLock.lock();
try {
System.out.println("写入数据: " + value);
data = value;
} finally {
writeLock.unlock();
}
}
}
在这个例子中,read() 方法使用读锁,允许多个线程并发读取;write() 方法使用写锁,确保写操作的原子性和排他性。
立即学习“Java免费学习笔记(深入)”;
锁的获取与释放注意事项
使用读写锁时,必须遵循正确的加锁和释放流程,避免死锁或资源泄漏。
- 每次 lock() 必须对应一次 unlock(),建议放在 finally 块中执行。
- 写锁可以降级为读锁(先获取写锁,再获取读锁,然后释放写锁),但不能反过来升级(读锁不能直接转为写锁)。
- 同一线程可重复获取读锁或写锁(重入),但获取次数需与释放次数匹配。
公平性与非公平模式
ReentrantReadWriteLock 支持构造时指定是否使用公平策略:
// 非公平模式(默认) ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); // 公平模式 ReentrantReadWriteLock fairLock = new ReentrantReadWriteLock(true);
公平模式下,锁会按照线程请求的顺序分配,避免线程饥饿,但吞吐量可能降低。非公平模式则允许插队,提高性能,适合大多数场景。
基本上就这些。合理使用读写锁能显著提升并发读场景下的性能,关键是区分清楚读写操作,并确保锁的正确释放。










