0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ConcurrentHashMap的概述

电子设计 来源:电子设计 作者:电子设计 2020-12-24 14:42 次阅读

数据结构

jdk1.7

jdk1.8

如果头节点是Node类型,其后就是一个普通的链表;如果头节点是TreeNode类型,它的后面就是一颗红黑树,TreeNode是Node的子类。链表和红黑树之间可以相互转换:初始的时候是链表,当链表中的元素超过某个阈值时,把链表转换成红黑树;反之,当红黑树中的元素个数小于某个阈值时,再转换为链表。

历史版本对比

从JDK1.7版本的ReentrantLock+Segment+HashEntry,到JDK1.8版本中synchronized+CAS+HashEntry+红黑树。代码量从原来的1000多行变成了 6000多 行,实现上也和原来的分段式存储有很大的区别。

1.数据结构

取消了Segment分段锁的数据结构,取而代之的是数组+链表+红黑树的结构。使用红黑树,当一个槽里有很多元素时,查询时间复杂度从原来的遍历链表O(n),变成遍历红黑树O(logN),Hash冲突的问题也会得到较好的解决

2.锁的粒度:

JDK1.7采用segment的分段锁机制实现线程安全,其中segment继承自ReentrantLock。JDK1.8采用CAS+Synchronized保证线程安全。原来是对需要进行数据操作的Segment加锁,现调整为对每个头节点分别加锁,其并发度,就是Node数组的长度,初始长度为16,这降低了锁的粒度。

3.并发的扩容:

在JDK 7中,一旦Segment的个数在初始化的时候确立,不能再更改,并发度被固定。之后只是在每个Segment内部扩容,这意味着每个Segment独立扩容,互不影响,不存在并发扩容的问题。但在JDK 8中,相当于只有1个Segment,当一个线程要扩容Node数组的时候,其他线程还要读写,因此处理过会更复杂。

4.代码实现上的区别:

sizeCtl:

多个线程的共享变量,是操作的控制标识符,它的作用不仅包括threshold的作用,在不同的地方有不同的值也有不同的用途。

-1代表正在初始化

-N 表示正在进行扩容操作。此时sizeCtl的高16位代表的是当前的容量(并不是数值等于容量大小) 低16位代表线程数 容量16的话计算rs = 32795 也就是 1000 0000 0001 1011 可以看出不同的容量对应不同rs值, rs << 16 的值为 11111111111111111111111111111111 10000000000110110000000000000000, 0-15位用于统计参与扩容的线程数, 16-31位用于代表扩容时容器的大小。

正数或0代表hash表还没有被初始化,这个数值表示初始化或下一次进行扩容的大小,这一点类似于扩容阈值的概念。后面可以看到,它的值始终是当前ConcurrentHashMap容量的0.75倍,这与loadfactor是对应的。

MOVED,TREEBIN,RESERVED :

MOVED,TREEBIN,RESERVED是用来表示特殊节点的哈希值。该类特殊节点均不含实际元素,且其哈希值被设置为负数和普通节点区分。


// ForwardingNode标记节点的hash值(表示正在扩容)

static final int MOVED = -1; // hash for forwarding nodes

// TreeBin节点的hash值,它是对应桶的根节点

static final int TREEBIN = -2; // hash for roots of trees

static final int RESERVED = -3; // hash for transient reservations

审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    7048

    浏览量

    89078
  • 代码
    +关注

    关注

    30

    文章

    4790

    浏览量

    68654
收藏 人收藏

    评论

    相关推荐

    缓存之美——如何选择合适的本地缓存?

    Guava cache是Google开发的Guava工具包中一套完善的JVM本地缓存框架,底层实现的数据结构类似于ConcurrentHashMap,但是进行了更多的能力拓展,包括缓存过期时间设置、缓存容量设置、多种淘汰策略、缓存监控等,下面简单介绍下这些功能及其使用方式。
    的头像 发表于 11-17 14:24 311次阅读
    缓存之美——如何选择合适的本地缓存?

    AM/DM37x概述

    电子发烧友网站提供《AM/DM37x概述.pdf》资料免费下载
    发表于 10-14 11:32 0次下载
    AM/DM37x<b class='flag-5'>概述</b>

    TAS2563设备特性和控制概述

    电子发烧友网站提供《TAS2563设备特性和控制概述.pdf》资料免费下载
    发表于 10-08 11:49 0次下载
    TAS2563设备特性和控制<b class='flag-5'>概述</b>

    TI Wi-Fi测试策略概述

    电子发烧友网站提供《TI Wi-Fi测试策略概述.pdf》资料免费下载
    发表于 09-20 10:46 1次下载
    TI Wi-Fi测试策略<b class='flag-5'>概述</b>

    Jacinto 7显示子系统概述应用说明

    电子发烧友网站提供《Jacinto 7显示子系统概述应用说明.pdf》资料免费下载
    发表于 09-14 10:00 0次下载
    Jacinto 7显示子系统<b class='flag-5'>概述</b>应用说明

    转换 SDIO 的电压产品概述

    电子发烧友网站提供《转换 SDIO 的电压产品概述.pdf》资料免费下载
    发表于 09-13 10:29 0次下载
    转换 SDIO 的电压产品<b class='flag-5'>概述</b>

    PCle链路培训概述

    电子发烧友网站提供《PCle链路培训概述.pdf》资料免费下载
    发表于 09-11 09:16 0次下载
    PCle链路培训<b class='flag-5'>概述</b>

    AM263到AM263P迁移概述

    电子发烧友网站提供《AM263到AM263P迁移概述.pdf》资料免费下载
    发表于 08-30 10:58 0次下载
    AM263到AM263P迁移<b class='flag-5'>概述</b>

    毫米波生产测试概述

    电子发烧友网站提供《毫米波生产测试概述.pdf》资料免费下载
    发表于 08-27 09:44 0次下载
    毫米波生产测试<b class='flag-5'>概述</b>

    内部补偿高级电流模式(ACM)概述

    电子发烧友网站提供《内部补偿高级电流模式(ACM)概述.pdf》资料免费下载
    发表于 08-26 14:55 1次下载
    内部补偿高级电流模式(ACM)<b class='flag-5'>概述</b>

    人工智能概述

    人工智能关键技术概述
    发表于 07-17 17:17 0次下载

    Parksonx XC6206系列线性稳压器概述

    Parksonx XC6206系列线性稳压器概述
    的头像 发表于 05-30 13:28 963次阅读
    Parksonx XC6206系列线性稳压器<b class='flag-5'>概述</b>

    基站供配电系统概述

    通信基站供配电系统概述基站供配电系统基本组成基站供配电系统特点功能 机房环境控制系统 
    发表于 05-06 10:13 1次下载

    linux命令概述

    电子发烧友网站提供《linux命令概述.pdf》资料免费下载
    发表于 03-11 09:18 3次下载

    光伏逆变器拓扑概述及关键技术

    光伏逆变器拓扑概述及关键技术
    的头像 发表于 02-21 09:47 815次阅读
    光伏逆变器拓扑<b class='flag-5'>概述</b>及关键技术