Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ConcurrentHashMap的put方法

ConcurrentHashMap的put方法

原创
作者头像
在下是首席架构师
发布于 2022-08-01 13:13:45
发布于 2022-08-01 13:13:45
8600
举报
文章被收录于专栏:从入门到出门从入门到出门
  • 计算key的哈希值
  • for自旋保证put成功
    • 如果没有初始化就初始化table
      • 有可能多个线程去调用initTable()方法去初始化,用cas加锁就行了,成功一次就行了
    • 通过与哈希取模计算数组下标,如果下标节点为null,就通过cas放进数组当前下标的位置
    • 如果当前下标有值,并且发现当前节点正在做扩容迁移操作,就去帮助扩容
    • 如果既有值,又没在扩容,就锁住这个数组下标节点,开始进行put操作
      • 第一种情况当前节点是一个链表
        • 遍历整个链表
        • 判断hash相同,并且key也相同,则覆盖
        • 如果hash不存在,此时已经遍历到了最后一个节点e,然后把当前的key/value添加到链表e节点的后i面,尾插法
      • 第二种情况当前节点是红黑树
        • 将节点放入红黑树,具体怎么放的参考我另一篇同系列下的文章之红黑树
    • put进去之后,会对链表长度进行判断,如果链表的长度大于等于8,进行扩容或者转化为红黑树
      • 链表的扩容
        • 如果tab的长度小于64,则调用tryPresize()方法进行扩容
        • 链表的扩容的本质是16->32,将数组扩容一倍,然后将老数组的数据迁移到新的数组
        • 如果为空就初始化数组,跟之前的initTable()方法一样
        • 如果已经是最大容量了,直接返回
        • 判断sizeCtl是否小于0,因为只有在扩容中的时候sizeCtl才会小于0变成-1,
        • 多线程扩容,高16位表示当前的扩容标记,保证唯一性,低16位表示当前扩容的线程数量,每增加一个扩容线程,就会在低16位+1
          • 实现数据转移 transfer()
          • 计算每个线程处理数据的区间大小,默认最小是16,当数组长度大时,会扩大区间大小
          • 链表的情况
          • 遍历旧链表,使用hash&新数组长度重新计算数组下标位置,
          • ln表示低位链表,hn表示高位链表
          • 低位链表表示遍历到某一个链表节点时发现这个节点及其后方节点都不需要变,直接将后面的所有节点变为一个链表
          • 红黑树的情况
          • 左旋右旋...
  • 扩容完成之后,统计个数,table的size+1
    • HashMap里面是有一个成员变量 size来统计个数
    • 如果竞争不激烈的情况下,直接用cas将baseCount+1
    • 如果竞争激烈的情况下,采用counterCells数组进行计数
    • counterCells长度为2,随机负载,落到0下标就对0下标的value进行cas操作,落到1下标就对1下标进行cas操作
    • 这样就将竞争程度下降了一倍,统计size()的时候,遍历counterCells数组,将数组值进行累加,然后baseCount+counterCells数组累加的数。
    • 如果counterCells长度为2不够,counterCells会动态扩容。

下面这两个连接可以再加上拳打

震惊!ConcurrentHashMap里面也有死循环,作者留下的“彩蛋”了解一下? - 掘金 这道面试题我真不知道面试官想要的回答是什么

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ConcurrentHashMap源码分析
本文基于jdk1.8对concurrentHashMap的源码进行分析,以put()方法为入口对concurrentHashMap的扩容机制,size计算方式等代码进行分析
Java进阶之路
2022/08/03
4160
ConcurrentHashMap源码分析
精妙绝伦的并发艺术品 — ConcurrentHashMap是如何保证线程安全的
我们知道,在日常开发中使用的HashMap是线程不安全的,而线程安全类HashTable只是简单的在方法上加锁实现线程安全,效率低下,所以在线程安全的环境下我们通常会使用ConcurrentHashMap,但是又为何需要学习ConcurrentHashMap?用不就完事了?我认为学习其源码有两个好处:
架构师修炼
2021/12/01
1K0
精妙绝伦的并发艺术品 — ConcurrentHashMap是如何保证线程安全的
万字图文——ConcurrentHashMap源码深度解析
本次ConcurrentHashMap的源码解析是针对JDK8,内容比较多,具体大纲请见下方截图:
爪哇缪斯
2023/05/10
7030
万字图文——ConcurrentHashMap源码深度解析
ConcurrentHashMap的底层实现与深度分析
在Java并发编程中,ConcurrentHashMap是一个非常重要的数据结构,它提供了一种线程安全的哈希表实现。随着Java版本的迭代,ConcurrentHashMap的实现也在不断优化,以更好地支持高并发场景。本文将深入探讨ConcurrentHashMap的底层存储结构、红黑树转换时机、核心属性sizeCtl、散列算法、计数器的安全机制以及size方法的实现策略。通过对这些功能点的详细分析,我们将揭示ConcurrentHashMap如何在高并发环境下保持高效性和线程安全性。
小马哥学JAVA
2024/11/15
2220
ConcurrentHashMap的底层实现与深度分析
JDK1.8 中 ConcurrentHashMap源码分析
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情
鳄鱼儿
2024/05/22
940
JDK1.8 中 ConcurrentHashMap源码分析
Java集合 - ConcurrentHashMap
技术是为了解决问题而生的,ConcurrentHashMap 解决了多个线程同时操作一个 HashMap 时,可能出现的内部问题。当多个线程同时操作一个 HashMap 时,有可能会出现多线程同时修改一个共享变量(HashMap 类的成员变量),导致数据被覆盖,产生意想不到的错误。
真正的飞鱼
2023/01/14
3340
我是这样给阿里面试官吹 ConcurrentHashMap的
因为上篇文章HashMap已经讲解的很详细了,因此此篇文章会简单介绍思路,再学习并发HashMap就简单很多了,上一篇文章中我们最终知道HashMap是线程不安全的,因此在老版本JDK中提供了HashTable来实现多线程级别的,改变之处重要有以下几点。
浅羽技术
2020/12/07
7930
我是这样给阿里面试官吹 ConcurrentHashMap的
嘿嘿,我就知道面试官接下来要问我 ConcurrentHashMap 底层原理了,看我怎么秀他
上篇文章介绍了 HashMap 源码后,在博客平台广受好评,让本来己经不打算更新这个系列的我,仿佛被打了一顿鸡血。真的,被读者认可的感觉,就是这么奇妙。
烟雨星空
2020/06/16
5650
嘿嘿,我就知道面试官接下来要问我 ConcurrentHashMap 底层原理了,看我怎么秀他
爆肝ConcurrentHashMap
特别说明:除第一小节以外,其他均都是以JDK 1.8的ConcurrentHashMap进行分析,本文信息量略大,每一份坚持都是值得被尊重的,希望你可以坚持读完这篇文章,也希望这篇文章对各位读者朋友有所帮助。
shysh95
2021/05/11
1.2K0
JDK之ConcurrentHashMap 原
    注:分析JDK8的ConcurrentHashMap,JDK6/7上的实现和JDK8上的不一样。
克虏伯
2019/04/15
4880
JDK之ConcurrentHashMap
                                                                            原
JDK 8 ConcurrentHashMap
ConcurrentHashMap是Java中的一个线程安全的哈希表实现,它是HashMap的一个并发版本。它提供了一种高效的方式来在多线程环境下进行并发访问和更新。与普通的HashMap不同,ConcurrentHashMap使用了锁分段技术,将整个哈希表分成多个段(Segment),每个段维护着一个独立的哈希表。这样,在多线程环境下,不同的线程可以同时访问和修改不同的段,从而提高了并发性能。
一个风轻云淡
2023/10/15
1640
ConcurrentHashMap 源码分析
ConcurrentHashMap 源码分析 1. 在阅读源码时做了大量的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限,并且代码阅读起来没有 IDE 方便,所以在 github 上提供JDK1.8 的源码、详细的注释及测试用例。欢迎大家 star、fork ! 2. 由于个人水平有限,对源码的分析理解可能存在偏差或不透彻的地方还请大家在评论区指出,谢谢! 1. 前言    终于到这个类了,其实在前面很过很多次这个类,因为这个类代码量比较大,并且涉及到并发的问题,还有一点就是这个代码有些真
lwen
2018/04/17
1.5K0
ConcurrentHashMap 源码分析
详解ConCurrentHashMap源码(jdk1.8)
ConCurrentHashMap是一个支持高并发集合,常用的集合之一,在jdk1.8中ConCurrentHashMap的结构和操作和HashMap都很类似:
用户10384376
2023/02/26
2820
详解ConCurrentHashMap源码(jdk1.8)
Java并发容器--ConcurrentHashMap
  1、不安全:大家都知道HashMap不是线程安全的,在多线程环境下,对HashMap进行put操作会导致死循环。是因为多线程会导致Entry链表形成环形数据结构,这样Entry的next节点将永远不为空,就会产生死循环获取Entry。具体内容见HashMap随笔。
在周末
2019/09/11
4730
Java的ConcurrentHashMap
ConcurrentHashMap是Java中的一个线程安全且高效的HashMap实现。
用户3467126
2019/07/25
5810
Java的ConcurrentHashMap
深入解析 ConcurrentHashMap 实现内幕,吊打面试官?没问题
在开发中,我们经常使用 HashMap 容器来存储 K-V 键值对,但是在并发多线程的情况下,HashMap 容器又是不安全的,因为在 put 元素的时候,如果触发扩容操作,也就是 rehash ,就会将原数组的内容重新 hash 到新的扩容数组中,但是在扩容这个过程中,其他线程也在进行 put 操作,如果这两个元素 hash 值相同,可能出现同时在同一数组下用链表表示,造成闭环,导致在get时会出现死循环,所以HashMap是线程不安全的。
平头哥的技术博文
2019/12/10
5020
JUC学习笔记(二)—ConcurentHashMap
Unsafe:是CAS的核心类,由于Java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据。 常见方法:
Monica2333
2020/06/19
5670
ConcurrentHashMap源码阅读
1. 前言 HashMap是非线程安全的,在多线程访问时没有同步机制,并发场景下put操作可能导致同一数组下的链表形成闭环,get时候出现死循环,导致CPU利用率接近100%。 HashTable是线程安全的,使用synchronized锁住整个table的方式来保证并发访问下的线程安全,但效率却比较低下。因为线程1调用HashTable的put同步方法时,线程2的put或get等方法则进入阻塞状态,所以竞争越激烈,效率越低。 ConcurrentHashMap是支持高并发、高吞吐量的线程安全的Map实现。
butterfly100
2018/04/17
1.1K0
ConcurrentHashMap源码阅读
ConcurrentHashMap学习
ConcurrentHashMap学习 属性 //最大容量 2的30次方 private static final int MAXIMUM_CAPACITY = 1 << 30; //初始容量 private static final int DEFAULT_CAPACITY = 16; /** * 虚拟机限制的最大数组长度,在ArrayList中有说过,jdk1.8新引入的, * ConcurrentHashMap的主体代码中是不使用这个的,主要用在Collection.toArray
晓果冻
2022/09/08
5830
ConcurrentHashMap学习
ConcurrentHashMap源码学习
既然有了HashMap为什么还会出现ConcurrentHashMap?同时ConcurrentHashMap具有什么优势?ConcurrentHashMap与HashMap、HashTable有什么区别?ConcurrentHashMap中的sizeCtl有几种值,这些值代表的是什么状态?ConcurrentHashMap使用了哪些锁?DEFAULT_CONCURRENCY_LEVEL表示什么,有什么用?
路行的亚洲
2020/07/17
5470
相关推荐
ConcurrentHashMap源码分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档