在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错误