繁体   English   中英

双重检查锁定的特殊情况?

[英]Special case of double checked locking?

所以我有这段代码,其中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的典型情况,因为由于编译器可以对事件进行重新排序,所以在插入映射时,可能尚未完全初始化该锁,因此下一个请求相同锁的线程可能会可能尚未完全初始化。

现在,我遇到的问题是,此问题是多线程应用程序的常见问题:从映射中获取内容,如果没有,则创建并添加。

  1. 这真的是DCL的情况吗?
  2. 如果是这样,您将如何解决。 (我们使用的简单明了的方法是创建一个锁池,当从池中提取一个锁时,将插入一个新锁)
  3. 如果还是这样,是否已在java8中修复

您在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()原子操作的使用。 我们也乐观地创建了一个新的Lock,但是如果我们丢失了比赛条件,我们将其丢弃,并使用比赛获胜者锁。

所以以某种方式我没有收到任何通知,所以对迟到的回复感到抱歉。 我想到了如果没有放置的内容,则始终(无时无刻)总是创建一个对象是有代价的,所以我想避免这种情况。 但我想成本是最低的,所以我将使用此解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM