6

我在面试时问了一个问题:如何实现独占写入HashMap和非独占读取的 getter 和 setter。假设以下代码:

public class MyClass {

     private HashMap map = new HashMap();


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

2 回答 2

14

试试这个

class MyClass<K, V> {
    private HashMap<K, V> map = new HashMap<K, V>();
    private ReadWriteLock rwl = new ReentrantReadWriteLock();
    private Lock rl = rwl.readLock();
    private Lock wl = rwl.writeLock();

    public V get(Object k) {
        rl.lock();
        try {
            return map.get(k);
        } finally {
            rl.unlock();
        }
    }

    public V put(K k, V v) {
        wl.lock();
        try {
            return map.put(k, v);
        } finally {
            wl.unlock();
        }
    }
}
于 2013-03-31T13:38:57.323 回答
8

ConcurrentHashMap使用锁分条策略:它有(使用默认设置)16 个锁,每个锁保护 1/16 的 hashmap 桶。

简单地使用volatile并没有真正的帮助,因为某些操作需要是原子的,并且volatile只提供可见性保证。

另一种方法是完全同步地图(如 inCollections.synchronizedMapHashtable),但这种策略在高争用下的性能明显更差 - 根据您的用例,它可能足够好。


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 回答