Are final static variables thread safe in Java?

2019-01-21 22:47发布

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()) {
                ...
            }
        }
     }

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.

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?

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;

or

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.)

8条回答
对你真心纯属浪费
2楼-- · 2019-01-21 23:38

Aren't you are actually asking if the static initialization of sharedData is thread safe and only executed once?

And yes, that is the case.

Of course many people here have correctly pointed out that the contents of sharedData can still be modified.

查看更多
神经病院院长
3楼-- · 2019-01-21 23:39

No. Except if they are immutable.

The only thing they do is

  • Be class level accesible
  • Avoid the reference to be changed.

Still if your attribute is mutable then it is not thread safe.

See also: Do we synchronize instances variables which are final?

It is exactly the same except they are class level.

查看更多
登录 后发表回答