オブジェクトを作成するこのシングルトンがあります。現在、次のようになっています。
public ApplicationManagerSingleton {
....
private Map<String, Thing> map = new HashMap<String, Thing>();
public Thing getThingById( String id ) {
Thing t = null;
if ( !map.contains(id) ) {
t = longAndCostlyInitializationOfThing();
map.put(id, t );
}
return map.get(id);
}
}
明らかな問題は、2 つのスレッドが同じものにアクセスしようとすると、それらが重複してしまう可能性があることです。
だから私はロックを使用しました:
public ApplicationManagerSingleton {
private Map<String, Thing> map = new HashMap<Sring, Thing>();
public Thing getThingById(String id ) {
synchronized( map ) {
if (!map.contains(id)) {
t = initialize....
}
map.put(id, t);
}
returns map.get(id);
}
}
しかし、これは最悪です。新しいリソースが作成されるたびにしばらくの間マップをロックすることになるため、他のスレッドが別のことを望んでいるというデメリットがあります。
Java 5 の並行パッケージを使えばもっと良くなると確信しています。誰かが私を正しい方向に向けることができますか?
私が避けたいのは、他のことに関心のある他のスレッドのクラスまたはマップをロックすることです。