您的位置:首页 > 编程语言 > Java开发

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

2018-05-03 00:34 696 查看

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. 如果是红黑树,执行红黑树的插入代码。执行完毕,synchronized (f) 锁退出
  8. 最后还回去判断是否到达阀值,如到达变为红黑树结构。使用方法:treeifyBin(tab, i);
  9. treeifyBin(tab, i)方法执行过程:如果容量小于64,直接扩容,不需要转变成红黑树。否则,对链表的头结点加synchronized 锁,以他为根节点构造红黑树

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

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

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

ConcurrentHashMap的JDK1.8实现

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: