ReadWriteLock 維護一對鎖:讀鎖(共享鎖)與 寫鎖(排他鎖)。
適用於「讀多寫少」的共享數據場景,顯著提升並發吞吐量。
public class ReadWriteLockDemo {
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
private Object data;
public Object read() {
readLock.lock();
try {
// 模擬讀取耗時
Thread.sleep((long) (Math.random() * 100));
return data;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
} finally {
readLock.unlock();
}
}
public void write(Object newData) {
writeLock.lock();
try {
// 模擬寫入耗時
Thread.sleep((long) (Math.random() * 100));
this.data = newData;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
writeLock.unlock();
}
}
}
public class Cache {
private final Map cache = new HashMap<>();
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
private final Function loader; // 數據加載器(如查數據庫)
public Cache(Function loader) {
this.loader = loader;
}
public V get(K key) {
// 1. 嘗試讀鎖快速讀取
readLock.lock();
try {
V value = cache.get(key);
if (value != null) return value;
} finally {
readLock.unlock();
}
// 2. 升級為寫鎖(雙重檢查鎖定模式)
writeLock.lock();
try {
// 再次檢查,防止多線程並發加載同一 key
V value = cache.get(key);
if (value == null) {
value = loader.apply(key); // 昂貴操作:查 DB、遠程調用等
cache.put(key, value);
}
return value;
} finally {
writeLock.unlock();
}
}
public void invalidate(K key) {
writeLock.lock();
try {
cache.remove(key);
} finally {
writeLock.unlock();
}
}
}
ReentrantReadWriteLock 默認非公平,可構造時指定 true 為公平模式。在 8 核機器上,讀寫比 9:1 時,ReadWriteLock 吞吐量約為 synchronized 的 3-5 倍;寫操作佔比超過 30% 時優勢明顯縮小,甚至不如獨占鎖。