问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

ConcurrentHashMap是如何保证线程安全的?

发布网友 发布时间:2024-09-26 17:53

我来回答

1个回答

热心网友 时间:2024-10-06 19:27

ConcurrentHashMap相当于是HashMap的多线程版本,它的功能本质上和HashMap没什么区别。因为HashMap在并发操作的时候会出现各种问题,比如死循环问题、数据覆盖等问题。而这些问题,只要使用ConcurrentHashMap就可以完美地解决。那问题来到了,ConcurrentHashMap它是如何保证线程安全的呢?

1、JDK1.7实现原理

首先,我们来看JDK?1.7中ConcurrentHashMap的底层结构,它基本延续了HashMap的设计,采用的是数组?加?链表的形式。和HashMap不同的是,ConcurrentHashMap中的数组设计???分为大数组Segment和小数组HashEntry,来着这张图。

大树组Segment可以理解为一个数据库,而每个数据库(Segment)中又有很多张表(HashEntry),每个HashEntry中又有很多条数据,这些数据是用链表连接的。了解了ConcurrentHashMap的基本结构设计,我们再来看它的线程安全实现,就比较简单了。

接下来我们来对照JDK1.7中ConcurrentHashMap的put()方法源码实现。

因为Segment本身是基于ReentrantLock重入锁实现的加锁和释放锁的操作,这样就能保证多个线程同时访问ConcurrentHashMap时,同一时间只能有一个线程能够操作相应的节点,这样就保证了ConcurrentHashMap的线程安全。

也就是说ConcurrentHashMap的线程安全是建立在Segment加锁的基础上的,所以,我们称它为分段锁或者片段锁,如图中所示。

那JDK1.8又是如何实现的呢?

2、JDK1.8优化内容

在JDK1.7中,ConcurrentHashMap虽然是线程安全的,但因为它的底层实现是数组加链表的形式,所以在数据比较多情况下,因为要遍历整个链表,会降低访问性能。所以,JDK1.8以后采用了数组?加??链表?加?红黑树的方式优化了ConcurrentHashMap的实现,具体实现如图所示。

当链表长度大于8,并且数组长度大于64时,链表就会升级为红黑树的结构。JDK?1.8中的ConcurrentHashMap虽然保留了Segment的定义,但这,仅仅是为了保证序列化时的兼容性,不再有任何结构上的用处了。

那在JDK?1.8中ConcurrentHashMap的源码是如何实现的呢?它主要是使用了CAS?加?volatile?或者?synchronized?的方式来保证线程安全。

我们可以从源码片段中看到,添加元素时首先会判断容器是否为空,

如果为空则使用????volatile????加???CAS????来初始化,

如果容器不为空,则根据存储的元素计算该位置是否为空。

如果根据存储的元素计算结果为空则利用???CAS???设置该节点;

如果根据存储的元素计算为空不为空,则使用??synchronized???,然后,遍历桶中的数据,并替换或新增节点到桶中,

最后再判断是否需要转为红黑树。这样就能保证并发访问时的线程安全了。

如果把上面的执行用一句话归纳的话,就相当于是ConcurrentHashMap通过对头结点加锁来保证线程安全的。

这样设计的好处是,使得锁的粒度相比Segment来说更小了,发生hash冲突?和??加锁的频率也降低了,在并发场景下的操作性能也提高了。而且,当数据量比较大的时候,查询性能也得到了很大的提升。

2、总结

最后,我们来总结一下:

1、ConcurrentHashMap在JDK?1.7中使用的数组?加?链表的结构,其中数组分为两类,大树组Segment?和?小数组?HashEntry,而加锁是通过给Segment添加ReentrantLock重入锁来保证线程安全的。

2、ConcurrentHashMap在JDK1.8中使用的是数组?加?链表?加?红黑树的方式实现,它是通过?CAS?或者?synchronized??来保证线程安全的,并且缩小了锁的粒度,查询性能也更高。

ConcurrentHashMap中有很多设计思想是值得我们去学习和借鉴的,比如说锁的粒度控制、分段锁的设计等等,都可以应用在实际的业务开发场景中。我们通过学习这些底层原理从中获取很多的设计思路,帮助我们更高效地去解决实际问题。

好了,关于ConcurrentHashMap的分享就讲到这里,听懂的小伙伴,请关注点个赞,下次不迷路。

本文为“Tom弹架构”原创,转载请注明出处。技术在于分享,我分享我快乐!\ 如果本文对您有帮助,欢迎关注和点赞;如果您有任何建议也可留言评论或私信,您的支持是我坚持创作的动力。关注微信公众号『 Tom弹架构 』可获取更多技术干货!

原文:https://juejin.cn/post/7097046521794789412

热心网友 时间:2024-10-06 19:25

ConcurrentHashMap相当于是HashMap的多线程版本,它的功能本质上和HashMap没什么区别。因为HashMap在并发操作的时候会出现各种问题,比如死循环问题、数据覆盖等问题。而这些问题,只要使用ConcurrentHashMap就可以完美地解决。那问题来到了,ConcurrentHashMap它是如何保证线程安全的呢?

1、JDK1.7实现原理

首先,我们来看JDK?1.7中ConcurrentHashMap的底层结构,它基本延续了HashMap的设计,采用的是数组?加?链表的形式。和HashMap不同的是,ConcurrentHashMap中的数组设计???分为大数组Segment和小数组HashEntry,来着这张图。

大树组Segment可以理解为一个数据库,而每个数据库(Segment)中又有很多张表(HashEntry),每个HashEntry中又有很多条数据,这些数据是用链表连接的。了解了ConcurrentHashMap的基本结构设计,我们再来看它的线程安全实现,就比较简单了。

接下来我们来对照JDK1.7中ConcurrentHashMap的put()方法源码实现。

因为Segment本身是基于ReentrantLock重入锁实现的加锁和释放锁的操作,这样就能保证多个线程同时访问ConcurrentHashMap时,同一时间只能有一个线程能够操作相应的节点,这样就保证了ConcurrentHashMap的线程安全。

也就是说ConcurrentHashMap的线程安全是建立在Segment加锁的基础上的,所以,我们称它为分段锁或者片段锁,如图中所示。

那JDK1.8又是如何实现的呢?

2、JDK1.8优化内容

在JDK1.7中,ConcurrentHashMap虽然是线程安全的,但因为它的底层实现是数组加链表的形式,所以在数据比较多情况下,因为要遍历整个链表,会降低访问性能。所以,JDK1.8以后采用了数组?加??链表?加?红黑树的方式优化了ConcurrentHashMap的实现,具体实现如图所示。

当链表长度大于8,并且数组长度大于64时,链表就会升级为红黑树的结构。JDK?1.8中的ConcurrentHashMap虽然保留了Segment的定义,但这,仅仅是为了保证序列化时的兼容性,不再有任何结构上的用处了。

那在JDK?1.8中ConcurrentHashMap的源码是如何实现的呢?它主要是使用了CAS?加?volatile?或者?synchronized?的方式来保证线程安全。

我们可以从源码片段中看到,添加元素时首先会判断容器是否为空,

如果为空则使用????volatile????加???CAS????来初始化,

如果容器不为空,则根据存储的元素计算该位置是否为空。

如果根据存储的元素计算结果为空则利用???CAS???设置该节点;

如果根据存储的元素计算为空不为空,则使用??synchronized???,然后,遍历桶中的数据,并替换或新增节点到桶中,

最后再判断是否需要转为红黑树。这样就能保证并发访问时的线程安全了。

如果把上面的执行用一句话归纳的话,就相当于是ConcurrentHashMap通过对头结点加锁来保证线程安全的。

这样设计的好处是,使得锁的粒度相比Segment来说更小了,发生hash冲突?和??加锁的频率也降低了,在并发场景下的操作性能也提高了。而且,当数据量比较大的时候,查询性能也得到了很大的提升。

2、总结

最后,我们来总结一下:

1、ConcurrentHashMap在JDK?1.7中使用的数组?加?链表的结构,其中数组分为两类,大树组Segment?和?小数组?HashEntry,而加锁是通过给Segment添加ReentrantLock重入锁来保证线程安全的。

2、ConcurrentHashMap在JDK1.8中使用的是数组?加?链表?加?红黑树的方式实现,它是通过?CAS?或者?synchronized??来保证线程安全的,并且缩小了锁的粒度,查询性能也更高。

ConcurrentHashMap中有很多设计思想是值得我们去学习和借鉴的,比如说锁的粒度控制、分段锁的设计等等,都可以应用在实际的业务开发场景中。我们通过学习这些底层原理从中获取很多的设计思路,帮助我们更高效地去解决实际问题。

好了,关于ConcurrentHashMap的分享就讲到这里,听懂的小伙伴,请关注点个赞,下次不迷路。

本文为“Tom弹架构”原创,转载请注明出处。技术在于分享,我分享我快乐!\ 如果本文对您有帮助,欢迎关注和点赞;如果您有任何建议也可留言评论或私信,您的支持是我坚持创作的动力。关注微信公众号『 Tom弹架构 』可获取更多技术干货!

原文:https://juejin.cn/post/7097046521794789412
ConcurrentHashMap是如何保证线程安全的?

2、JDK1.8优化内容在JDK1.7中,ConcurrentHashMap虽然是线程安全的,但因为它的底层实现是数组加链表的形式,所以在数据比较多情况下,因为要遍历整个链表,会降低访问性能。所以,JDK1.8以后采用了数组?加??链表?加?红黑树的方式优化了ConcurrentHashMap的实现,具体实现如图所示。当链表长度大于8,并且...

concurrenthashmap是怎么实现线程安全的

ConcurrentMap能够保证每一次调用(例如一次putIfAbsent)都是原子操作,不受多线程影响,但并不保证多次调用之间也是原子操作。 以上实现的GetKeyBM方法中,ConcurrentMap的方法被调用了许多次,不同线程之间必然存在着竞争关系,导致最终结果...

ConcurrentHashMap如何实现高效地线程安全?

ConcurrentHashMap允许一边更新、一边遍历,也就是说在Iterator对象遍历的时候,ConcurrentHashMap也可以进行remove,put操作,且遍历的数据会随着remove,put操作产出变化

线程安全的集合有哪些

ConcurrentHashMap:它是一种线程安全的哈希表实现,允许多个线程同时对其进行读写操作。与传统的Hashtable相比,ConcurrentHashMap采用了分段锁技术,即不同的线程可以操作不同的段,从而实现了真正的并发访问。这使得ConcurrentHashMap在高并发场景下表现出较高的性能。CopyOnWriteArrayList:这是一种线程安全的...

concurrenthashmap原理18

并发哈希表(ConcurrentHashMap)的原理是什么?并发哈希表是Java集合框架中的一种数据结构,它结合了哈希表和锁机制,实现了线程安全的哈希表操作。其主要原理如下:1. 使用哈希函数将键(Key)映射到哈希表中相应的槽位(Bucket)。2. 在槽位中存储键值对(Key-Value Pair),并使用锁来保护槽位的...

Java高并发编程实战7,ConcurrentHashMap详解

在JDK1.8中,ConcurrentHashMap进一步改进,采用数组+链表/红黑树的形式,直接使用volatile避免数据冲突,并利用synchronized和CAS算法确保线程安全。CopyOnWrite策略利用冗余实现读写分离,避免了锁竞争。操作流程是:读操作在原容器进行,写操作在新容器,写完后指向新容器,旧容器被回收。这样既支持高并发读,...

ConcurrentHashMap

ConcurrentHashMap通常只被看做并发效率更高的Map,用来替换其他线程安全的Map容器,比如Hashtable和Collections.synchronizedMap。线程安全的容器,特别是Map,很多情况下一个业务中涉及容器的操作有多个,即复合操作,而在并发执行时,线程安全的容器只能保证自身的数据不被破坏,和数据在多个线程间是可见的,但...

如何让HashMap变成线程安全的

分别如下:方法一:通过Collections.synchronizedMap()返回一个新的Map,这个新的map就是线程安全的。 这个要求大家习惯基于接口编程,因为返回的并不是HashMap,而是一个Map的实现。方法二:重新改写了HashMap,具体的可以查看java.util.concurrent.ConcurrentHashMap. 这个方法比方法一有了很大的改进。

HashMap线程不安全?ConcurrentHashMap线程安全?为啥呢?

1.HashMap不是线程安全的,而ConcurrentHashMap是线程安全的。2.ConcurrentHashMap采用锁分段技术, 将整个Hash桶进行了分段segment,也就是将这个大的数组分成了几个小的片段segment ,而且每个小的片段segment上面都有锁存在,那么在插入元素的时候就需要先找到应该插入到哪一个片段segment,然后再在这个...

Java高并发编程实战7,ConcurrentHashMap详解

8版本,ConcurrentHashMap进一步优化,其数据结构转变为数组与链表或红黑树的结合,锁的粒度更细,性能更佳。当链表长度超过8时,链表会升级为红黑树。同时,ConcurrentHashMap废弃了segment,直接使用volatile HashEntry对象存储,通过volatile关键字避免冲突。此外,它利用synchronized和CAS算法保证线程安全。

java注解component mybatis与hibernate区别的对比 sql慢查询如何优化 java事务注解失效场景 编程式事务 springmvc和springboot的区别 JAVA事务 redis方法汇总 java反射
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
...今年高考345(理科)想学医,请问报陕西哪些专科学院好? 宁夏师范学院院系介绍 ...了还一无所有一事无成,还没有任何学历,是不是注定一生不会有任何成就... 学历不好,难道就真的一点机会也不给吗? 头发打薄之后会永远发量少吗-头发打薄多久能厚回去 我把刘海打薄了需要多久才能长回原来的厚度? 说说各位认识的那些没有多少学历,但大获成功的人吧 ...没文化没学历只能干这个,说现在我已经被社会淘汰了。 可今天晚上厨房的水管又爆裂啦,迫切寻求帮助 2024没学历最吃香的职业 张亮曾经被芒果打造为“男神”,为何最后并没有成功? 他骂哭谢娜,邓超黄渤见面了要鞠躬,身价上亿座驾却如此低调,他是谁呢... 你心目中哪位男神厨艺最好呢?来说说看? 瑞士名威手表M8028s 名威手表好不好刚买块 手机里面还在放歌,为什么就是屏幕亮不了? 怎么从汽水音乐下载歌曲 纪梵希黑丝带唇膏色号 纪梵希黑丝带唇膏试色 当天蝎男遇见了狮子女会怎样 天蝎男狮子女匹配指数是多少 狮子座与天蝎座配对指数,天蝎座与狮子座好准哦 狮子座和天蝎座的人匹配指数 如果消费者的合法权益遭到侵害如何处理 当自己的合法权益受到侵害时怎么办 教师节英语干货分享|教师节英语祝福语|英语范文|名言例句统统都有_百度... 在桂林花鸟市场买的 叫 潜水艇 的鱼怎么养?它的原名是什么?它的各种习... 微信中的玫瑰花是什么含义? 我想知道一些关于神州五号和六号的详细资料 我国于2005年10月12日90成功发射了"神舟"六号航天飞船,它环绕地球飞 ... 微信的玫瑰花代表什么意思? 神舟六号绕地球飞一圈要多长时间 循环数组无锁队列的原理与实现 《满江红》古诗原文及翻译? 满江红经典诗词赏析,10首经典《满江红》 哔哩哔哩直播姬手机录屏直播,怎么才能让对方听得见说话,就这样可以 神舟六号载人飞船任务执行情况 神舟六号在轨 美的冰箱和容声冰箱的区别? 冰箱是容声好还是美的好? ...语文与生活第三:你们那个地方有这类俗语吗? 如何通过CMD命令解决CF游戏中的"out of memory"问题? 什么?公证书居然有真伪!一招教你如何鉴定 鱼肉馅饺子(鱼肉馅饺子如何调馅) 从建外SOHO到四通桥怎么坐车? 联想电脑摄像头灰色带锁怎么办呢? 从三元桥到人民大学该做什么车?? 上地到北京国际展览中心(静安庄庄老国展)乘车方式(地铁)?需要多长... 屠狗之辈怎么造句 樊哙怎么造句 温岭市豆豆虫贸易有限公司怎么样? 斑比狗是什么品牌