ReadWriteMap使用了ReentrantReadWriteLock来包装Map,使得它能够在多线程间被安全的共享,并仍然能够避免“读-写”或者“写-写”冲突。现实中,ConcurentHashMap的性能已经足够好了(经查看源代码,里面的是每个hash计算后的散列区域作为锁,这个大大减少了锁之间的竞争),
ConcurrentHashMap源码:
public V get(Object key) {
int hash = hash(key.hashCode());
return segmentFor(hash).get(key, hash);//使用该hash的对象调用get方法,也就是意为着该对象就是锁
}
final Segment<K,V> segmentFor(int hash) {
return segments[(hash >>> segmentShift) & segmentMask];
}
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key)) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
V readValueUnderLock(HashEntry<K,V> e) {
lock();//锁便是hash对象
try {
return e.value;
} finally {
unlock();
}
}
所以你可以使用它,而不必使用新的解决方案,如果你需要并发的部分只有部分哈希map,但是如果你需要为LinkedHashMap这种可替换元素的Map提供更多的并发访问,那么这项技术是非常有用的。
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteMap <K,V> {
private final Map<K,V> map;
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock r = lock.readLock();
private final Lock w = lock.writeLock();
public ReadWriteMap(Map<K, V> map){
this.map = map;
}
public void put(K key, V value){
w.lock();
try{
return map.put(key, value);
}finally{
w.unlock();
}
}//remove(), putAll(), clear()也完全类似
public V get(Object key){
r.lock();
try{
return map.get(key);
}finally{
r.unlock();
}
}//对于其他的只读Map方法也完全类似
}