返回信息流在 http://www.alidata.org/archives/969 看到java读写锁在cache中的一个用法
private ConcurrentHashMap<String, ServerGroup> route2SG = null;
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public Cache2() {
route2SG = new ConcurrentHashMap<String, ServerGroup>();
}
public ServerGroup get(String routeKey) throws IOException {
ServerGroup sg = null;
try {
lock.readLock().lock();
sg = route2SG.get(routeKey);
if (sg == null) {
lock.readLock().unlock();
lock.writeLock().lock();
sg = route2SG.get(routeKey);
if (sg == null) {
sg = getServerGroup(routeKey);
route2SG.put(routeKey, sg);
}
lock.readLock().lock();
lock.writeLock().unlock();
}
} catch (IOException e) {
lock.writeLock().unlock();
throw (e);
}
lock.readLock().unlock();
return sg;
}
其中的get函数,发现cache中没有自己想要的元素,就用写锁写进来,这个时候直接返回不就好了么,为什么要把写锁降级为读锁呢?读锁后来什么也没做啊。。求大神解答
这是一条镜像帖。来源:北邮人论坛 / java / #34354同步于 2014/9/3
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
java 读写锁的一个问题
ylewxh
2014/9/3镜像同步11 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
【 在 nuanyangyang 的大作中提到: 】
: 同不懂同求问。还是问问原作者吧。
连暖神也不会啊。。
原作者在blog上因为第三个实现被喷了,而且很久远的帖子,应该问不到了
我好像以前见过代码,就是降级为读锁之后,再去读一遍,然后返回。因为退出写锁之后,在获得读锁之前,可能别的线程对缓存进行了更改,导致应该返回的不再是刚刚put进去的值了。但是刚找了找,以前的代码找不见了。。
【 在 container 的大作中提到: 】
只有一个目的,让等待读的线程可以读,但是等待写的线程要等读的线程完事后再度
这样的话,写锁直接释放就可以了吧,这样别人可以读,也可以写,为啥还要再申请读锁呢?申请了之后啥也没干啊
申请读锁之后,其它等待读的线程就可以进入,但是等待写的线程就要靠边站了,结果肯定不一样,他就是不让别人马上写
【 在 ylewxh 的大作中提到: 】
: 只有一个目的,让等待读的线程可以读,但是等待写的线程要等读的线程完事后再度
: 这样的话,写锁直接释放就可以了吧,这样别人可以读,也可以写,为啥还要再申请读锁呢?申请了之后啥也没干啊
【 在 container 的大作中提到: 】
: 申请读锁之后,其它等待读的线程就可以进入,但是等待写的线程就要靠边站了,结果肯定不一样,他就是不让别人马上写
嗯嗯,这样确实别人可以马上读,但是不能马上写
实现这样的功能有什么好处么?是一般cache都这样做,还是得看具体情景呢?
不知道啊,你可以根据结果分析一下有什么好处,别的我就不知道了
【 在 ylewxh 的大作中提到: 】
:
: 嗯嗯,这样确实别人可以马上读,但是不能马上写
: 实现这样的功能有什么好处么?是一般cache都这样做,还是得看具体情景呢?
是不是照着javadoc里的Sample写的啊,感觉一样
class CachedData {
Object data;
volatile boolean cacheValid;
final 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();
try {
// 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();
} finally {
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
try {
use(data);
} finally {
rwl.readLock().unlock();
}
}
}}