Java中的最终静态变量是线程安全的吗? [英] Are final static variables thread safe in Java?

查看:33
本文介绍了Java中的最终静态变量是线程安全的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了很多,但还没有找到明确的答案.

I've read around quite a bit but haven't found a definitive answer.

我有一个如下所示的课程:

I have a class that looks like this:

    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 的许多实例将在多线程环境中创建.

And I'm wondering if it is thread safe to access sharedData from instances of Foo (as is shown in the constructor and in doSomethingUseful()). Many instances of Foo will be created in a multi-threaded environment.

我的意图是 sharedData 在静态初始化器中初始化,之后不再修改(只读).

My intention is that sharedData is initialized in the static initializer and not modified thereafter (read-only).

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

What I've read is that immutable objects are inherently thread safe. But I've only seen this in what seems to be the context of instance variables. Are immutable static variables thread safe?

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

The other construct I found was a ConcurrentHashMap. I could make sharedData of type ConcurrentHashMap but do the HashMaps it contains also have to be of type ConcurrentHashMap? Basically..

private static final ConcurrentHashMap<String, HashMap> sharedData;

private static final ConcurrentHashMap<String, ConcurrentHashMap> sharedData;

或者它会更安全(但简单地克隆()成本更高)?

Or would it be safer (yet more costly to simply clone())?

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

TIA.

(静态初始化器已被编辑以提供更多上下文.)

(Static initializer has been edited to give more context.)

推荐答案

sharedDatareference 是 final 的,因为它永远无法更改,因此是线程安全的.Map 的内容是 NOT 线程安全的,因为它需要最好用 Guava ImmutableMap 实现或 java.util.Collections.unmodifiableMap()<包装/code> 或使用 java.util.concurrent 包中的 Map 实现之一.

the reference to sharedData which is final is thread safe since it can never be changed. The contents of the Map is NOT thread safe because it needs to be either wrapped with preferably a Guava ImmutableMap implementation or java.util.Collections.unmodifiableMap() or use one of the Map implementations in the java.util.concurrent package.

只有BOTH你才能在地图上获得全面的线程安全.任何包含的 Map 都必须是不可变的,或者也是并发实现之一.

Only if you do BOTH will you have comprehensive thread safety on the Map. Any contained Maps need to be immutable or one of the concurrent implementations as well.

默认情况下克隆是浅克隆,它只会返回对容器对象的引用而不是完整的副本.在普遍可用的信息中详细记录了原因.

cloning by default is a shallow clone, it will just return references to container objects not complete copies. It is well documented in generally available information on why.

这篇关于Java中的最终静态变量是线程安全的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆