HashMap
インタビューで、排他的な書き込みと非排他的な読み取りのためにゲッターとセッターを実装する方法について質問しました。次のコードを想定します。
public class MyClass {
private HashMap map = new HashMap();
// HOW TO implement Getter and Setter for exclusive writing and non-exclusive reading
}
HashMap
インタビューで、排他的な書き込みと非排他的な読み取りのためにゲッターとセッターを実装する方法について質問しました。次のコードを想定します。
public class MyClass {
private HashMap map = new HashMap();
// HOW TO implement Getter and Setter for exclusive writing and non-exclusive reading
}
ConcurrentHashMap
ロック ストライピング戦略を使用します。(デフォルト設定では) 16 個のロックがあり、それぞれがハッシュマップ バケットの 1/16 を保護します。
一部の操作はアトミックである必要があり、可視性の保証のみを提供するため、単に使用するだけvolatile
では実際には役に立ちません。volatile
Collections.synchronizedMap
別の方法として、(またはのように) マップを完全に同期するHashtable
こともできますが、競合が多い場合のこのような戦略のパフォーマンスは大幅に低下します。ユース ケースによっては、それで十分な場合もあります。
Evgeniy の提案に代わるものは、一種の「copyonwritemap」です。ほとんどのシナリオでは効率的ではありません。
class MyClass<K, V> {
//note: map needs to be volatile to completely remove synchronization
//at the getter level
private volatile Map<K, V> map = new HashMap<K, V>();
private final Object lock = new Object();
public V get(Object k) {
return map.get(k);
}
public V put(K k, V v) {
synchronized (lock) { //for exclusive writing
Map<K, V> newMap = new HashMap<K, V> (map); //copy map
V value = newMap.put(k, v);
//volatile guarantees that this will be visible from the getter
map = newMap;
return value;
}
}
}