【Java并发编程】23、ConcurrentHashMap原理分析(1.7和1.8版本对比)

jdk 1.8版本

ConcurrentHashMap在1.8中的实现,相比于1.7的版本基本上全部都变掉了。首先,取消了Segment分段锁的数据结构,取而代之的是数组+链表(红黑树)的结构。而对于锁的粒度,调整为对每个数组元素加锁(Node)。

put的步骤大致如下:

    1. 参数校验。
    2. 若table[]未创建,则初始化。table的初始化和扩容采用CAS无锁设计,通过状态 sizeCtl 来控制线程的并发操作:U.compareAndSwapInt(this, SIZECTL, sc, -1)
    3. 当table[i]后面无节点时,直接创建Node(无锁操作)。也是通过CAS实现:return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
    4. 如果当前正在扩容,则帮助扩容并返回最新table[]。
    5. 然后在链表或者红黑树中追加节点。此过程通过synchronized (f) 锁定当前node实现线程安全
    6. 如果是链表,遍历链表,发现相同key则替换旧值,没有发现相同key则添加到链表的末尾
    7. 如果是红黑树,
    8. 最后还回去判断是否到达阀值,如到达变为红黑树结构。使用方法:treeifyBin(tab, i);

 get()方法没有加锁操作,步骤如下:

    1. 首先定位到table[]中的i。
    2. 若table[i]存在,则继续查找。
    3. 首先比较链表头部,如果是则返回。
    4. 然后如果为红黑树,查找树。
    5. 如果不是红黑树,循环链表查找。

参考网上的详细说明资料如下:

ConcurrentHashMap的JDK1.8实现

猜你喜欢

转载自www.cnblogs.com/wangzhongqiu/p/8981824.html