Java集合:ConcurrentHashMap

一、引入背景(Why)

1. 在多线程环境下,HashMap的put会导致扩容,扩容引起死循环,导致CPU使用率100%

2. 可以使用HashTable和Collections.synchronizedMap(hashMap)可以解决多线程的问题

3. HashTable和Collections.synchronizedMap(hashMap)对读写进行加一个全局锁,一个线程读写map的元素,其余线程必须等待,性能不好

4. ConcurrentHashMap也加了锁,但是只锁了map的一部分,其余线程可以继续读写没锁住的部分,优化了操作性能

 

二、JDK1.7的实现(了解):Segment分段锁+HashEntry+ReentrantLock

1. HashEntry是键值对,用来存储数据

2. 桶是由若干个HashEntry连接起来的链表

3. Segment分段锁继承ReentrantLock,每个Segment对象锁住若干个桶

4. 一个ConcurrentHashMap实例中,包含由若干个Segment对象组成的数组

5. HashEntry->HashBucket->Segment->ConcurrentHashMap,一层一层被包含

 

三、JDK1.8的实现(理解):Node+CAS+Synchronized,锁的粒度更小

1. 数据结构:抛弃了臃肿的Segment分段锁机制,采用CAS+Synchronized来保证并发更新的安全,底层依然是数组+链表+红黑树的存储结构

2. table,默认为16大小的数组,第一次put值才会初始化

3. Node,保存key-value,hash值和下一个node地址

class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    volatile V val;  //volatile保证并发的可见性
    volatile Node<K,V> next;  //volatile保证并发的可见性
}

4. put实现,采用CAS+Synchronized实现并发插入或者更新,当链表长度大于8,会把链表转为红黑树

final V putVal(K key, V value, boolean onlyIfAbsent) {
    if (key == null || value == null) throw new NullPointerException();
    int hash = spread(key.hashCode());
    int binCount = 0;
    for (Node<K,V>[] tab = table;;) {
        Node<K,V> f; int n, i, fh;
        if (tab == null || (n = tab.length) == 0)
            tab = initTable();
        else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
            if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value, null)))
                break;                   // no lock when adding to empty bin
        }
        else if ((fh = f.hash) == MOVED)
            tab = helpTransfer(tab, f);
        ...省略部分代码
    }
    addCount(1L, binCount);
    return null;
}

5. size实现:使用一个volatile类型的变量baseCount记录元素个数,通过addCount()更新

6. 扩容,数组使用volatile修饰,表示数组的地址是volatile,而不是表示数据元素是volatile,在扩容的时候,对其他线程保持可见性

7. get操作,源码没有加锁,因为Node的值和指针,使用volatile修饰的

8. JDK1.8的ConcurrentHashMap存在bug,会进入死循环,1.9修复了

 

四、红黑树的实现分析

1. 红黑树是一种特殊的二叉树

2. 主要用来存储有序的数据

3. 可以高效检索,时间复杂度为O(lgn)

 

 

 

参考:

https://www.jianshu.com/p/c0642afe03e0

https://www.jianshu.com/p/f6730d5784ad

https://www.jianshu.com/p/23b84ba9a498

https://www.jianshu.com/p/e694f1e868ec

 

posted @ 2019-09-28 17:44  牧云文仔  阅读(738)  评论(0编辑  收藏  举报