私はConcurrentMap < String、SomeObject >オブジェクトを持っています。 SomeObjectが存在する場合はそれを返すメソッドを作成するか、新しいSomeObjectを作成してマップに入れ、存在しない場合はそれを返します。必要に応じてキーを追加するときにConcurrentMapを同期する必要はありますか?
理想的には、ConcurrentMapのputIfAbsent(key, new SomeObject(key))
を使用することができますが、そのたびに新しいSomeObject(キー)が作成されることになり、非常に無駄に思えます。
は、だから私は、次のコードに頼っが、それはこれを処理するための最良の方法だということを確認していない:
public SomeValue getSomevalue(String key){
SomeValue result = concurrentMap.get(key);
if (result != null)
return result;
synchronized(concurrentMap){
SomeValue result = concurrentMap.get(key);
if (result == null){
result = new SomeValue(key);
concurrentMap.put(key, result);
}
return result;
}
}
コードは正しいですが、同期ブロックにputIfAbsentを使用できます。より最適になるでしょう。 –
@GuillaumeF。あなたはより最適な意味を説明できますか?その時点で、同期ブロック内でキーをチェックしてからヌル値を取得するため、キーがないことがわかります。 – isapir
私は同期ブロック内のテストを削除することを意味します。あなたは既に同期の前にテストを行っているので、2回目のテストがnull以外の何かを返す確率は非常に低いです。 putIfAbsentをオブジェクトの新しいインスタンスに使用するのが最適なのは、まれにしか失敗しないためです。また、同期ブロックを完全に削除することもできます。 –