所以我有这个代码,其中lockMap是ConcurrentHashMap
//Creation of locks
Lock getLock(String key) {
Lock lock = lockMap.get(key);
if (lock == null) {
synchronized (lockMap) {
lock = lockMap.get(key);
if (lock == null) {
lock = new ReentrantLock();
lockMap.put(key, lock);
}
}
}
return lock;
}
在代码审查期间,有人提到这是DCL的典型案例,因为,由于编译器可以对事件进行重新排序,因此当插入映射时锁可能尚未完全初始化,然后下一个线程请求相同的锁可能尚未完全初始化。
现在,我遇到的问题是这个问题是多线程应用程序的常见问题:从地图中获取内容,如果没有,则创建并添加。
答案 0 :(得分:2)
你在ConcurrentHashMap中有锁的事实......令人困惑,但是,假设你知道你在做什么,最好的方法是:
Lock getLock(String key) {
Lock lock = lockMap.get(key);
if (lock == null) {
lock = new ReentrantLock();
Lock race = lockMap.putIfAbsent(key, lock);
if (race != null) {
//there was a race, we lost.
lock = race;
}
}
return lock;
}
请注意putIfAbsent()原子操作的使用。我们也乐观地创造了一个新的锁,但如果我们失去了比赛条件,我们就把它扔出去,并使用比赛获胜者锁。
答案 1 :(得分:0)
所以不知怎的,我没有收到任何通知,对于迟到的回复感到遗憾。 我想到了如果不存在,但是,总是创造一个对象的成本(大部分时间),所以我想避免这种情况。 但我想成本很低,所以我会使用这个解决方案。