快速实现一个缓存
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();}}
}