今天再来说说JUC下的HashMap的put方法
(https://blog.csdn.net/saratanglei/article/details/100163740)(https://blog.csdn.net/saratanglei/article/details/100314965)
上源码:
![](https://img.haomeiwen.com/i11967682/c39c60f6aba14fb8.png)
赶脚特别长是不是,其实拆解来看并没有很复杂。
没工夫的可直接滚轮最后查看完整注释版。
1、初始化变量,中间看到的initTable是不是很眼熟,就是之前讲的initTable 见第一Part
![](https://img.haomeiwen.com/i11967682/233709378bf075fa.png)
2、找到对应的位置 tabAt返回的是Node,也是Unsafe获取的,如果空就直接Cas插入啦。当然如果并发Cas是失败。失败后会在上一个for中继续重试
![](https://img.haomeiwen.com/i11967682/00f621bf24ad85d9.png)
![](https://img.haomeiwen.com/i11967682/16760cf4bde40405.png)
3、判断是否在扩容移动。这边扩容是concurrentHashMap的精华。我们日后详细分解
![](https://img.haomeiwen.com/i11967682/60061189db3899a2.png)
4、接下来就是位置上有值,使用synchronized 加锁,先判断是否是链表,如果是那就遍历去比较,发现相同的就会替换,如果没有那就在末尾追加。如果Node是红黑树那就调用红黑树。(ps:红黑树数据结构自行查阅资料,涉及不少知识。包括红黑树的结构,树的自平衡等等)
![](https://img.haomeiwen.com/i11967682/abcb07dca0f3cc56.png)
5、在完成上面的put后,就需要检查链表是不是需要转换成红黑树了
![](https://img.haomeiwen.com/i11967682/e999b18221fe054a.png)
6、最后是元素统计
![](https://img.haomeiwen.com/i11967682/4753bc821654ff68.png)
最后附上一张完整的注释截图。
![](https://img.haomeiwen.com/i11967682/42511dea4674f0ba.png)
总结:
ConcurrentHashMap的线程安全是如何保证的?
看到这里其实能够大概看到端倪,Doug lea大量使用了Unsafe的Cas的原子操作,并且使用了synchronized上锁,及volatile的同步来保证安全的。
![](https://img.haomeiwen.com/i5953175/d5a72572a032541e.png)
网友评论