ReentrantReadWriteLock 針對讀操作遠多於寫操作的場景優化:
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
Lock readLock = rwLock.readLock(); // 共享鎖
Lock writeLock = rwLock.writeLock(); // 獨佔鎖
// 讀操作
readLock.lock();
try {
// 讀取共享資料
} finally {
readLock.unlock();
}
// 寫操作
writeLock.lock();
try {
// 修改共享資料
} finally {
writeLock.unlock();
}
public class ReadWriteLockDemo {
public static String testVal = "Initiation";
static class Reader extends Thread {
private final Lock readLock;
Reader(Lock readLock, String name) { this.readLock = readLock; setName(name); }
public void run() {
while (true) {
readLock.lock();
try {
System.out.println(getName() + ": read - " + testVal);
} finally { readLock.unlock(); }
sleep(1000);
}
}
}
static class Writer extends Thread {
private final Lock writeLock;
Writer(Lock writeLock, String name) { this.writeLock = writeLock; setName(name); }
public void run() {
while (true) {
writeLock.lock();
try {
System.out.println(getName() + ": write");
testVal = "1111".equals(testVal) ? "2222" : "1111";
} finally { writeLock.unlock(); }
sleep(2000);
}
}
}
public static void main(String[] args) {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
Lock r = lock.readLock(), w = lock.writeLock();
new Reader(r, "R1").start();
new Reader(r, "R2").start();
new Reader(r, "R3").start();
new Reader(r, "R4").start();
new Writer(w, "W1").start();
}
}
R1: read - Initiation R3: read - Initiation ← 讀-讀並發,同時輸出 W1: write ← 寫鎖獨佔,阻塞後續讀/寫 R2: read - 1111 R4: read - 1111 R3: read - 1111 R1: read - 1111 ...
可見:寫入期間所有讀者阻塞;寫入完成後,多個讀者再次並發讀取最新值。
new ReentrantReadWriteLock(true) 選擇公平模式(預設非公平,吞吐量更高)。writeLock 支援 newCondition(),讀鎖不支援等待/通知。| 特性 | synchronized | Lock (ReentrantLock/ReadWriteLock) |
|---|---|---|
| API 豐富度 | 無 | tryLock()、lockInterruptibly()、Condition、公平鎖 |
| 多條件變數 | 單一 wait set | 多個 Condition 實現精準喚醒 |
| 鎖範圍控制 | 方法/塊級 | 任意範圍,跨方法鎖定 |
| 可中斷性 | 不可中斷 | lockInterruptibly() 可響應中斷 |
| 效能(低競爭) | 優化後極佳 | 略高開銷 |
| 效能(高競爭/讀多寫少) | 無讀寫分離 | ReadWriteLock 顯著優勢 |