我在面试时问了一个问题:如何实现独占写入HashMap
和非独占读取的 getter 和 setter。假设以下代码:
public class MyClass {
private HashMap map = new HashMap();
// HOW TO implement Getter and Setter for exclusive writing and non-exclusive reading
}
我在面试时问了一个问题:如何实现独占写入HashMap
和非独占读取的 getter 和 setter。假设以下代码:
public class MyClass {
private HashMap map = new HashMap();
// HOW TO implement Getter and Setter for exclusive writing and non-exclusive reading
}
试试这个
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();
}
}
}
ConcurrentHashMap
使用锁分条策略:它有(使用默认设置)16 个锁,每个锁保护 1/16 的 hashmap 桶。
简单地使用volatile
并没有真正的帮助,因为某些操作需要是原子的,并且volatile
只提供可见性保证。
另一种方法是完全同步地图(如 inCollections.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;
}
}
}