6

HashMapインタビューで、排他的な書き込みと非排他的な読み取りのためにゲッターとセッターを実装する方法について質問しました。次のコードを想定します。

public class MyClass {

     private HashMap map = new HashMap();


      // HOW TO implement Getter and Setter for exclusive writing and non-exclusive reading
}
4

2 に答える 2

8

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;
        }
    }
}
于 2013-03-31T12:32:52.353 に答える