ロジックをセンスチェックするための並行マップの特定の使用法について話し合いたいと思いました...
を使用した場合ConcurrentHashMap
、ファミリアを実行できます
private final ConcurrentHashMap<K, V> map = new ConcurrentHashMap<K, V>();
public V getExampleOne(K key) {
map.putIfAbsent(key, new Object());
return map.get(key);
}
しかし、 と の間のマップからアイテムを削除すると、上記のメソッドがコレクションに存在しなくなったものを返すという競合状態が存在することに気付きました。これはうまくいくかもしれないし、うまくいかないかもしれませんが、私のユースケースではうまくいかないと仮定しましょう。putIfAbsent
get
私が本当に望んでいるのは、すべてをアトミックにすることです。そう、
public V getExampleTwo(K key) {
return map.putIfAbsent(key, new Object());
}
しかし、これが展開するにつれて
if (!map.containsKey(key))
return map.put(key, value); [1]
return map.get(key);
これは、行 [1] がnull
最初に使用されたときに返されます (つまり、map.put
以前の値が返され、最初に使用された場合は になりますnull
)。
このインスタンスで null を返すことはできません
それは私に次のようなものを残します;
public V getExampleThree(K key) {
Object object = new Object();
V value = locks.putIfAbsent(key, object);
if (value == null)
return object;
return value;
}
最後に、私の質問です。上記の例はセマンティクスでどのように異なりますか?. getExampleThree
アトミック性を保証しgetExampleTwo
ますが、null リターンを正しく回避しますか? 他に問題はありgetExampleThree
ますか?
選択について少し議論したいと思っていました。ConcurrentHashMap
メソッドを呼び出すクライアントとget
マップから削除するメソッドを使用して非同期を使用できることを認識していますが、それは ConcurrentHashMap の目的 (非ブロッキングの性質) を無効にしているようです。データを正確に保つための唯一の選択肢ですか?
それが、ConcurrentHashMap を選択する理由の一部だと思います。操作した時点で表示/最新/正確であることを確認しますが、古いデータが問題になる場合は、さらに先に影響がある可能性があります...