ConcurrentHashMap基于JDK1.8源码剖析

前言

声明,本文用的是jdk1.8

前面章节回顾:

本篇主要讲解ConCurrentHashMap~

看这篇文章之前最好是有点数据结构的基础:

当然了,如果讲得有错的地方还请大家多多包涵并不吝在评论去指正~

一、ConCurrentHashMap剖析

ConCurrentHashMap在初学的时候反正我是没有接触过的,不知道你们接触过了没有~

这个类听得也挺少的,在集合中是比较复杂的一个类了,它涉及到了一些多线程的知识点。

不了解或忘记多线程知识点的同学也不要怕,哪儿用到了多线程的知识点,我都会简单介绍一下,并给出对应的资料去阅读的~

好了,我们就来开始吧~

1.1初识ConCurrentHashMap

ConCurrentHashMap的底层是:散列表+红黑树,与HashMap是一样的。

image

从前面的章节我们也可以发现:最快了解一下类是干嘛的,我们看源码的顶部注释就可以了!

我简单翻译了一下顶部的注释(我英文水平渣,如果有错的地方请多多包涵~欢迎在评论区下指正)

2018-04-14_092943.png

根据上面注释我们可以简单总结:

  • JDK1.8底层是散列表+红黑树
  • ConCurrentHashMap支持高并发的访问和更新,它是线程安全
  • 检索操作不用加锁,get方法是非阻塞的
  • key和value都不允许为null

1.2JDK1.7底层实现

上面指明的是JDK1.8底层是:散列表+红黑树,也就意味着,JDK1.7的底层跟JDK1.8是不同的~

JDK1.7的底层是:segments+HashEntry数组:

Xhimkj8.png

图来源:https://blog.csdn.net/panweiwei1994/article/details/78897275

  • Segment继承了ReentrantLock,每个片段都有了一个锁,叫做“锁分段

大概了解一下即可~

1.3有了Hashtable为啥需要ConCurrentHashMap

  • Hashtable是在每个方法上都加上了Synchronized完成同步,效率低下。
  • ConcurrentHashMap通过在部分加锁利用CAS算法来实现同步。

1.4CAS算法和volatile简单介绍

在看ConCurrentHashMap源码之前,我们来简单讲讲CAS算法和volatile关键字

CAS(比较与交换,Compare and swap) 是一种有名的无锁算法

CAS有3个操作数

  • 内存值V
  • 旧的预期值A
  • 要修改的新值B

当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做

  • 当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值(A和内存值V相同时,将内存值V修改为B),而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试(否则什么都不做)

看了上面的描述应该就很容易理解了,先比较是否相等,如果相等则替换(CAS算法)


接下来我们看看volatile关键字,在初学的时候也很少使用到volatile这个关键字。反正我没用到,而又经常在看Java相关面试题的时候看到它,觉得是一个挺神秘又很难的一个关键字。其实不然,还是挺容易理解的~

volatile经典总结:volatile仅仅用来保证该变量对所有线程的可见性,但不保证原子性

我们将其拆开来解释一下:

  • 保证该变量对所有线程的可见性
    • 在多线程的环境下:当这个变量修改时,所有的线程都会知道该变量被修改了,也就是所谓的“可见性”
  • 不保证原子性
    • 修改变量(赋值)实质上是在JVM中分了好几步,而在这几步内(从装载变量到修改),它是不安全的

如果没看懂或者想要深入了解其原理和可参考下列博文:

1.5ConCurrentHashMap域

域对象有这么几个:

rjvoGhc.png

我们来简单看一下他们是什么东东:

image

初次阅读完之后,有的属性我也不太清楚它是干什么的,在继续阅读之后可能就明朗了~

1.6ConCurrentHashMap构造方法

ConcurrentHashMap的构造方法有5个:

2tXkMrh.png

具体的实现是这样子的:

image

可以发现,在构造方法中有几处都调用了tableSizeFor(),我们来看一下他是干什么的:

点进去之后发现,啊,原来我看过这个方法,在HashMap的时候.....

image

它就是用来获取大于参数且最接近2的整次幂的数...

赋值给sizeCtl属性也就说明了:这是下次扩容的大小~

1.7put方法

终于来到了最核心的方法之一:put方法啦~~~~

我们先来整体看一下put方法干了什么事:

image

接下来,我们来看看初始化散列表的时候干了什么事:initTable()

NxMQu59.png
  • 只让一个线程对散列表进行初始化

1.8get方法

从顶部注释我们可以读到,get方法是不用加锁的,是非阻塞的。

我们可以发现,Node节点是重写的,设置了volatile关键字修饰,致使它每次获取的都是最新设置的值

WxQJ58R.png
tBI4n51.png

二、总结

上面简单介绍了ConcurrentHashMap的核心知识,还有很多知识点都没有提及到,作者的水平也不能将其弄懂~~有兴趣进入的同学可到下面的链接继续学习。

下面我来简单总结一下ConcurrentHashMap的核心要点:

  • 底层结构是散列表(数组+链表)+红黑树,这一点和HashMap是一样的。
  • Hashtable是将所有的方法进行同步,效率低下。而ConcurrentHashMap作为一个高并发的容器,它是通过部分锁定+CAS算法来进行实现线程安全的。CAS算法也可以认为是乐观锁的一种~
  • 在高并发环境下,统计数据(计算size...等等)其实是无意义的,因为在下一时刻size值就变化了。
  • get方法是非阻塞,无锁的。重写Node类,通过volatile修饰next来实现每次获取都是最新设置的值
  • ConcurrentHashMap的key和Value都不能为null

参考资料:


明天要是无意外的话,可能会写Set集合,敬请期待哦~~~~

文章的目录导航https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y。为了大家方便,刚新建了一下qq群:742919422,大家也可以去交流交流。谢谢支持了!希望能多介绍给其他有需要的朋友

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,825评论 4 377
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,887评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,425评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,801评论 0 224
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,252评论 3 299
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,089评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,216评论 2 322
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 31,005评论 0 215
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,747评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,883评论 2 255
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,354评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,694评论 3 265
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,406评论 3 246
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,222评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,996评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,242评论 2 287
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 36,017评论 2 281