繁体   English   中英

为什么ConcurrentHashMap在双重检查锁定中起作用

[英]Why does ConcurrentHashMap work in Double Checked Locking

在“ Java Concurrency in Practice”一书中提到以下代码不是线程安全的:

@NotThreadSafe
public class DoubleCheckedLocking {

    private static Resource resource;

    public static Resource getInstance(){
        if(resource == null){
            synchronized (DoubleCheckedLocking.class){
                if(resource == null)
                    resource = new Resource();
            }
        }
        return resource;
    }
}

它不是线程安全的,因为:-一个线程可以创建Resource的新实例-另一个线程在“ if”条件下同时不能获得空引用,但是Resource对象不会完全初始化

在这个问题上是类似的代码。 资源存储在concurentHashMap中,人们说它是threadSafe。 像这样:

public class DoubleCheckedLocking2 {

    private static ConcurrentHashMap<String, ComplexObject> cache = new ConcurrentHashMap<String, ComplexObject>();

    public static ComplexObject getInstance(String key) {
        ComplexObject result = cache.get(key);
        if (result == null) {
            synchronized (DoubleCheckedLocking2.class) {
                ComplexObject currentValue = cache.get(key);
                if (currentValue == null) {
                    result = new ComplexObject();
                    cache.put(key, result);
                } else {
                    result = currentValue;
                }
            }
        }
        return result;
    }
}

为什么将值存储在ConcurrentHashMap中会使代码成为threadSafe 我认为ComplexObject仍可能不会完全初始化,并且此“部分对象”将保存在地图中。 其他线程将读取部分未完全初始化的对象。

我想我知道什么是“事前发生”,我已经分析了JDK 8.0_31中的代码,但我仍然不知道答案。

我知道诸如computeIfAbsentputIfAbsent之类的功能。 我知道这段代码可以用不同的方式编写。 我只是不知道使该代码成为线程安全的细节。

实际上发生在这里才是关键。 边缘从map.put(key, object)扩展到后续map.get(key) 之前发生事情 ,因此,您检索的对象至少与存储在地图中的对象保持最新。

暂无
暂无

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

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