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