阅读java并发编程实践第11章,11.4减少锁的竞争.
ConcurrentHashMap的实现使用了一个包含16个对象锁的数组,每个锁都负责同步hash buckets数组中的 1/16的元素;buckets中的第n个元素由locks中第 n除以16 个锁来守护.假设hash算法的实现能够提供合理的扩展性,并且关键字能够以统一的方式访问,这会将对于锁的请求减少到原来的1/16.这种基于分离锁设计的技术实现能够使得ConcurrentHashMap支持16个并发的请求.
但是分离锁的负面作用是:对容器加锁,进行独占访问变得更加困难,并且更加昂贵.
例如当buckets的负载度超过了阀值,容量需要被扩展,元素需要重新排序.然后放入一个更大的buckets的时候,我们必须获得所有的分离锁.
分离锁能够改进伸缩性能,因为它们支持不同的线程操作不同的数据(或者同一个数据结构的不同部分),而不会产生相互间的干扰.这一点对于那些对锁的竞争普遍大于锁守护数据的竞争的程序十分有益.
public class StropedMap
{
private static final int N_LOCKS = 16;
private final Node[] buckets;
private final Object[] locks;
public StropedMap(int numBuckets)
{
super();
buckets = new Node[numBuckets];
locks = new Object[N_LOCKS];
for(int i=0;i<this.buckets.length;i++){
synchronized(locks[i%N_LOCKS]){
buckets[i] = null;
}
}
}
class Node {
Object key;
Object value;
Node next;
public Node(Object key, Object value) {
super();
this.key = key;
this.value = value;
this.next = null;
}
}
}