gpt4 book ai didi

java - 这是 'double check' 反模式的情况吗? (获取一个map条目,不存在则创建)

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:40:30 25 4
gpt4 key购买 nike

我正在尝试做一个映射值的线程安全 getter ,如果它不存在,它也会创建该值:

private final static Map<String, MyObject> myMap = new HashMap<String, MyObject>();

public MyObject myGetter(String key) {
// Try to retrieve the object without synchronization
MyObject myObject = myMap.get(key);
if (myObject != null) {
return myObject;
}

// The value does not exist, so create a new object.
synchronized (myMap) {
myObject = myMap.get(key);
if (myObject == null) {
myObject = new MyObject(key);
myMap.put(key, myObject);
}
return myObject;
}
}

注意 myMap 成员变量是 final 的,其他任何地方都不能访问它。

如果不需要,我不希望创建 MyObject(我发现的一些其他模式建议可能导致为同一键创建多个模式)。

我知道 'double check' anti-pattern ,但我不确定这段代码是否适用于该反模式,因为它不是在此处创建的成员变量本身。

所以,我的问题是,这是否仍然是该反模式的一个案例,如果是:为什么?

编辑 1:

从评论来看,这里的一个解决方法是简单地接受“性能影响”(我猜影响很小),并且只将读取包含在同步块(synchronized block)中,如下所示:

private final static Map<String, MyObject> myMap = new HashMap<String, MyObject>();

public MyObject myGetter(String key) {
synchronized (myMap) {
MyObject myObject = myMap.get(key);
if (myObject == null) {
// The value does not exist, create a new object.
myObject = new MyObject(key);
myMap.put(key, myObject);
}
return myObject;
}
}

此外,我使用的是 Java 6,因此 ConcurrentHashMap.computeIfAbsent 不是此处的选项。

最佳答案

正如评论和您的编辑所指出的,这是双重检查锁定反模式的一种形式。

正确的实现是使用ConcurrentHashMap。您在评论中列出了您使用的是 Java 6,因此无法使用 computeIfAbsent。没关系,您仍然应该使用 ConcurrentHashMap#putIfAbsent

可以做类似double-check的操作

private final static ConcurrentMap<String, MyObject> myMap =
new ConcurrentHashMap<String, MyObject>();

public MyObject myGetter(String key) {
MyObject ref = myMap.get(key);
if(ref == null) {
ref = new MyObject(key);
MyOject put = myMap.putIfAbsent(key, ref);
if(put != null) {
// some other thread won put first
ref = put;
}
}
return ref;
}

在这种情况下,由于 CHM 具有非阻塞读取的特性,您仅锁定突变。

否则,您提供的编辑是线程安全(尽管效率低下)的实现。

关于java - 这是 'double check' 反模式的情况吗? (获取一个map条目,不存在则创建),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40105915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com