JDK 1.8 ConcurrentHashMap (三)——
2021-11-15 本文已影响0人
designer
今天再来说说JUC下的HashMap的put方法
(https://blog.csdn.net/saratanglei/article/details/100163740)(https://blog.csdn.net/saratanglei/article/details/100314965)
上源码:

赶脚特别长是不是,其实拆解来看并没有很复杂。
没工夫的可直接滚轮最后查看完整注释版。
1、初始化变量,中间看到的initTable是不是很眼熟,就是之前讲的initTable 见第一Part

2、找到对应的位置 tabAt返回的是Node,也是Unsafe获取的,如果空就直接Cas插入啦。当然如果并发Cas是失败。失败后会在上一个for中继续重试


3、判断是否在扩容移动。这边扩容是concurrentHashMap的精华。我们日后详细分解

4、接下来就是位置上有值,使用synchronized 加锁,先判断是否是链表,如果是那就遍历去比较,发现相同的就会替换,如果没有那就在末尾追加。如果Node是红黑树那就调用红黑树。(ps:红黑树数据结构自行查阅资料,涉及不少知识。包括红黑树的结构,树的自平衡等等)

5、在完成上面的put后,就需要检查链表是不是需要转换成红黑树了

6、最后是元素统计

最后附上一张完整的注释截图。

总结:
ConcurrentHashMap的线程安全是如何保证的?
看到这里其实能够大概看到端倪,Doug lea大量使用了Unsafe的Cas的原子操作,并且使用了synchronized上锁,及volatile的同步来保证安全的。
