ConcurrentHashMap源码详解

参考链接:【十四】Java集合之ConcurrentHashMap源码分析(1.8)_courrenthashmap1.8每个数组都有一个-CSDN博客

添加几个链接有1.7和1.8的源码:

1.7:

https://mbd.baidu.com/ug_share/mbox/4a83aa9e65/share?product=smartapp&tk=0aa47658f125c634236297085ef129d2&share_url=https%3A%2F%2Fyebd1h.smartapps.cn%2Fpages%2Fblog%2Findex%3FblogId%3D130015253%26_swebfr%3D1%26_swebFromHost%3Dbaiduboxapp&domain=mbd.baidu.com :1.7:

https://mbd.baidu.com/ug_share/mbox/4a83aa9e65/share?product=smartapp&tk=5af6dff65ad4fbfe8404472678be8a49&share_url=https%3A%2F%2Fyebd1h.smartapps.cn%2Fpages%2Fblog%2Findex%3FblogId%3D132049781%26_swebfr%3D1%26_swebFromHost%3Dbaiduboxapp&domain=mbd.baidu.com 

1.8的源码:

【多线程】ConcurrentHashMap1.8源码保姆级解析_concurrenthashmap源码分析1.8-CSDN博客

 

总括:数组+链表+红黑树。

为什么要用红黑树呢?因为在hash冲突严重的情况下,链化严重会导致查询效率变为O(n)。所以,引入红黑树。当链表长度大于8,数组长度大于64时,会树化。以空间换时间,查询效率变为O(nLognN)。

使用CAS+synchronized+volatile来保证并发安全。保证线程安全一定要保证:原子性,可见性,有序性。

内部类:

1.Node

这是Node的基类,也是其他Node的基类。整个table的结构就是Node数组,用volatile保证value和netNode在被修改时的可见性和有序性。

2.TreeNode

 红黑树Node,继承自Node。成员:父节点,左孩子节点,右孩子节点,前一个节点,颜色。

put元素时,使用CAS保证原子性。(根据数组长度减1再对hash值取余得到在Node数组中位于哪个下标,用tabAt获取数组中该下标的元素)。

如果链表长度>8,将链表转为红黑树(而这个方法中会判断数组值是否大于64,如果没有大于64,则只扩容)。

如果是第一个扩容的就开始,如果有别的线程在 扩容就帮助别的线程一起扩容。

扩容是怎样保证线程安全的?

   比如:现在的数组长度为32,线程A迁移0-15的桶,线程B迁移16-31的桶。当前哪些区间的桶被分配的临界值用一个变量表示,对他的修改是CAS的,所以多线程扩容安全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值