热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

jdk1.8版本ConcurrentHashMap在1.8中的实现,相比于1.7的版本基本上全部都变掉了。首先,取消了Segment分段锁的数据结构,取而代之的是数组+链表(红黑树)的结构。而对

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 <
    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实现

 


推荐阅读
author-avatar
手机用户2602925995
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有