ConcurrentHashMap使用了一种完全不同的加锁策略来提供更高的并发性和伸缩性。ConcurrentHashMap并不是将每个方法都在同一个锁上同步并使得每次只有一个线程访问容器,而是使用一种粒度更细的加锁机制来实现更大程度的共享,这种机制成为分段锁(lock striping)。这种机制中,任意数量的读取线程都可以并发访问Map,并且一定数量的线程可以并发修改Map。好处是:在并发环境下实现更高的吞吐量。
在HashTable以及synchronizedMap中,都是通过获取整个Map的锁以防止其他线程访问这个Map,但ConcurrentHashMap没有对整个Map加锁以提供独占访问。
典型应用场景:
使用map时,需要使用synchronized,这样计算的并发性能低下
public class Memoizer1 <A, V> implements Computable<A, V> {
private final Map<A, V> cache = new HashMap<A, V>();
private final Computable<A, V> c;
public Memoizer1(Computable<A, V> c) {
this.c = c;
}
public synchronized V compute(A arg) throws InterruptedException {
V result = cache.get(arg);
if (result == null) {
result = c.compute(arg);
cache.put(arg, result);
}
return result;
}
}
interface Computable <A, V> {
V compute(A arg) throws InterruptedException;
}
改成使用ConcurrentHashMap
public class Memoizer2 <A, V> implements Computable<A, V> {
private final Map<A, V> cache = new ConcurrentHashMap<A, V>();
private final Computable<A, V> c;
public Memoizer2(Computable<A, V> c) {
this.c = c;
}
public V compute(A arg) throws InterruptedException {
V result = cache.get(arg);
if (result == null) {
result = c.compute(arg);
cache.put(arg, result);
}
return result;
}
}
进一步的原理分析和比较,可以参考:
http://blog.youkuaiyun.com/liuzhengkang/article/details/2916620
http://www.douban.com/note/169672949/