ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HashMap扩容-多线程不安全和ConcurrentHashMap

2021-10-13 21:35:11  阅读:143  来源: 互联网

标签:扩容 ConcurrentHashMap hash HashMap 线程 put 多线程


1.7扩容过程:当键值对大小大于数组大小时进行扩容,数组扩容原来的2倍,然后对键重新rehash。

1.8扩容过程:不需要rehash,只要看原来hash值新增的bit是1还是0就好了,是0的话索引没有变,是1的话索引变成“原索引+oldCap”。省去了hash的时间。

为什么多线程不安全?

1.7死循环问题:在扩容过程里,多线程环境下可能发生死循环。如下:

线程1指向3,next指向7,线程1挂起。线程2扩容为下图2,因为是头插法,所以7是头节点。唤醒线程1,因为线程1之前指向的是3,节点3又被插入到7的前面,循环链表就产生了。

image

1.8put覆盖:线程A走到检测hash碰撞的代码,然后被挂起,线程B和线程A的key值一样,然后put值到map里,线程A被唤醒,它也去put值,就把Bput的值覆盖了。

ConcurrentHashMap通过CAS和经过锁优化的synchronized来保证多线程安全。CAS是Unsafe类里的方法,synchronized先开始是偏向锁,线程获取了锁一直没有竞争,那么持有偏向锁的线程在执行时不需要获取锁,轻量级锁是如果锁被持有了,线程获取不到锁,他不会挂起,而是自旋一段时间,等待锁释放。因为大部分情况下,占用锁的线程很快就执行完了。

ConcurrentHashMap的get方法不需要加锁,因为ConcurrentHashMap中存储数据采用的 Node 数组是采用了volatile来修饰的。

标签:扩容,ConcurrentHashMap,hash,HashMap,线程,put,多线程
来源: https://www.cnblogs.com/bllbl/p/15404298.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有