私はかなり読んだことがありますが、決定的な答えは見つかりませんでした。
私は次のようなクラスを持っています:
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でした。タイプConcurrentHashMapのsharedDataを作成できますが、それに含まれるHashMapもタイプConcurrentHashMapである必要がありますか?基本的に..
private static final ConcurrentHashMap<String, HashMap> sharedData;
また
private static final ConcurrentHashMap<String, ConcurrentHashMap> sharedData;
それとも、より安全でしょうか(ただし、単にclone()を実行する方がコストがかかります)。
this.myCopyOfData = sharedData.get(key).clone();
TIA。
(静的初期化子は、より多くのコンテキストを提供するように編集されています。)