ConcurrentHashMap实现线程安全的原理

版权声明:嘿嘿嘿 https://blog.csdn.net/luzhensmart/article/details/87654273

ConcurrentHashMap的实现原理。 
  ConcurrentHashMap定义了Segment内部类,看一下代码:

//Segment继承了ReentrantLock重入锁(这个概念这次先不看)
static final class Segment<K,V> extends ReentrantLock implements Serializable {
    //HashEntry与HashMap中类似,可以理解为一个单向链表元素,作为存放相同hash值,不同key的键值对,因为:ConcurrentHashMap通过数组形式存放多个Segment,用key的hash值做一次再hash,当做下标,识别当前键值对存放在segments数组中的哪个segment里。
    //这样一个Segment就相当于一个HashMap
    transient volatile HashEntry<K,V>[] table;
    V put(K key, int hash, V value, boolean onlyIfAbsent) {
        //在对Segment进行操作时,对当前对象Segment加锁
        lock();
        try {
        //数据操作
        } finally {
           unlock();
        }
    }

}

 ConcurrentHashMap通过数组形式存放多个Segment,用key的hash值做一次再hash当做下标识别当前键值对存放在哪个segment里。

final Segment<K,V>[] segments;
  public V put(K key, V value) {
        if (value == null)
            throw new NullPointerException();
        //用key的hashCode再做一次hash
        int hash = hash(key.hashCode());
        return segmentFor(hash).put(key, hash, value, false);
    }

 在对segment元素进行操作时加锁,这样当其它人线程操作当前ConcurrentHashMap对象时,只要key1的hash值(hash(key1.hashCode()))加锁key2的值(hash(key2.hashCode()))不同,就可以直接操作其它Segment元素。 
示意图: 

ConcurrentHashMap结构:

 

 ConcurrentHashMap 有 16 个 Segments 所以理论上,这个时候,最多可以同时支持 16 个线程并发写,只要它们的操作分别分布在不同的 Segment 上。这个值可以在初始化的时候设置为其他值,但是一旦初始化以后,它是不可以扩容的。

3 

HashMap结构: 

猜你喜欢

转载自blog.csdn.net/luzhensmart/article/details/87654273
今日推荐