Java并发编程实战~ReadWriteLock~
快速实现一个缓存
public class Cache<K,V> {
final Map<K, V> m = new HashMap<>();
final ReadWriteLock rwl = new ReentrantReadWriteLock();
// 读锁
final Lock r = rwl.readLock();
// 写锁
final Lock w = rwl.writeLock();
// 读缓存
public V get(K key) {
r.lock();
try {
return m.get(key);
}finally {
r.unlock();
}
}
// 写缓存
public V put(String key, Data v) {
w.lock();
try {
return m.put(key, v);
}finally {
w.unlock();
}
}
}
实现缓存的按需加载
public class Cache<K,V> {
final Map<K, V> m = new HashMap<>();
final ReadWriteLock rwl = new ReentrantReadWriteLock();
final Lock r = rwl.readLock();
final Lock w = rwl.writeLock();
public V getWithLoad(K key) {
V v = get(key);
// 缓存中存在,返回
if(v != null) {
return v;
}
// 缓存中不存在,查询数据库
w.lock();
try {
// 再次验证,其他线程可能已经查询过数据库
v = m.get(key);
if(v == null){
// 查询数据库
v= loadData(...);
m.put(key, v);
}
} finally{
w.unlock();
}
return v;
}
// 读缓存
public V get(K key) {
r.lock();
try {
return m.get(key);
}finally {
r.unlock();
}
}
}
读写锁的升级与降级
锁的升级--禁止
// 读缓存
r.lock();
try {
v = m.get(key);
if (v == null) {
w.lock();
try {
// 再次验证并更新缓存
// 省略详细代码
} finally{
w.unlock();
}
}
} finally{
r.unlock();
}
锁的降级--支持
public class CachedData {
Object data;
volatile boolean cacheValid;
final ReadWriteLock rwl = new ReentrantReadWriteLock();
// 读锁
final Lock r = rwl.readLock();
// 写锁
final Lock w = rwl.writeLock();
void processCachedData() {
// 获取读锁
r.lock();
if (!cacheValid) {
// 释放读锁,因为不允许读锁的升级
r.unlock();
// 获取写锁
w.lock();
try {
// 再次检查状态
if (!cacheValid) {
data = ...
cacheValid = true;
}
// 释放写锁前,降级为读锁
// 降级是可以的
r.lock();
} finally {
// 释放写锁
w.unlock();
}
}
// 此处仍然持有读锁
try {use(data);}
finally {r.unlock();}
}
}
