最终静态变量在Java中线程安全吗?

我已经阅读了很多,但是还没有找到确切的答案。

我有一堂课,看起来像这样:

    public class Foo() {

private static final HashMap<String, HashMap> sharedData;

private final HashMap myRefOfInnerHashMap;

static {

// time-consuming initialization of sharedData

final HashMap<String, String> innerMap = new HashMap<String, String>;

innerMap.put...

innerMap.put...

...a

sharedData.put(someKey, java.util.Collections.unmodifiableMap(innerMap));

}

public Foo(String key) {

this.myRefOfInnerHashMap = sharedData.get(key);

}

public void doSomethingUseful() {

// iterate over copy

for (Map.Entry<String, String> entry : this.myRefOfInnerHashMap.entrySet()) {

...

}

}

}

而且我想知道从Foo实例访问sharedData是否是线程安全的(如构造函数和doSomethingUseful()中所示)。Foo的许多实例将在多线程环境中创建。

我的意图是在静态初始化程序中初始化sharedData,此后不进行修改(只读)。

我读到的是,不可变对象本质上是线程安全的。但是我仅在实例变量的上下文中看到了这一点。不变静态变量线程安全吗?

我发现的另一个构造是ConcurrentHashMap。我可以使sharedData的类型为ConcurrentHashMap,但是它包含的HashMaps是否也必须为ConcurrentHashMap类型?基本上..

private static final ConcurrentHashMap<String, HashMap> sharedData;

要么

private static final ConcurrentHashMap<String, ConcurrentHashMap> sharedData;

还是更安全(简单地clone()会更昂贵)?

this.myCopyOfData = sharedData.get(key).clone();

TIA。

(已对静态初始值设定项进行了编辑,以提供更多上下文。)

回答:

该 到sharedData这是最后的是线程安全的,因为它永远不会改变。Map的内容 线程安全的,因为它最好用Guava

ImmutableMap实现包装,或者java.util.Collections.unmodifiableMap()java.util.concurrent包中使用Map实现之一。

只有当你做 将你对地图综合线程安全。任何包含的地图都必须是不可变的,或者也是并发实现之一。

.clone()从根本上被破坏,请远离

默认情况下,克隆是浅表克隆,它将仅返回对容器对象的引用而不是完整副本。关于为什么的一般可用信息中有很好的记录。

以上是 最终静态变量在Java中线程安全吗? 的全部内容, 来源链接: utcz.com/qa/428564.html

回到顶部