在JAVA1.5版本以后,JAVA API中提供了ReadWriteLock,此类是一个接口,在它的实现类中ReentrantReadWriteLock中有这样一段代码
class CachedData { Object data; volatile boolean cacheValid; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); // Recheck state because another thread might have acquired // write lock and changed state before we did. if (!cacheValid) { data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); rwl.writeLock().unlock(); // Unlock write, still hold read } use(data); rwl.readLock().unlock(); } }
以上代码是一个简单的缓存实现方式,根据以上思路写出如下代码
import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class CacheSystemTest { private Map<String, Object> cacheMap = new HashMap<String, Object>(); private ReadWriteLock rwl = new ReentrantReadWriteLock(); /** * 为了防止在多线程情景下数据安全问题,需要线程互斥,实现方式是用锁 * @param key * @return */ public Object get(String key){ rwl.readLock().lock(); //任何一个线程进来后,第一时间加上读锁 Object obj = null; try{ obj = cacheMap.get(key); if(obj == null){ rwl.readLock().unlock(); //在赋值前关闭读锁,并在此检查对象 if(obj == null){ rwl.writeLock().lock(); //打开一个写锁 try{ obj = "read write lock"; }finally{ rwl.writeLock().unlock(); //关闭写锁 rwl.readLock().lock(); //恢复正常读锁 } } } }finally{ rwl.readLock().unlock(); } return obj; } }
注:此锁最多支持65535个递归写入锁和读锁,如果试图超出则抛出Error错误