JDK 1.8 ConcurrentHashMap (二)—— putVal

今天再来说说JUC下的HashMap的put方法

上源码:

put的实现

赶脚特别长是不是,其实拆解来看并没有很复杂。

没工夫的可直接滚轮最后查看完整注释版。



1、初始化变量,中间看到的initTable是不是很眼熟,就是之前讲的initTable 见第一Part

初始化



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

插入前判断


Cas插入



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


moved状态



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

Hash一致的情况下



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

红黑树



6、最后是元素统计

addCount




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

截图真的不好截 +_+!


总结:

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

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

你可能感兴趣的:(JDK 1.8 ConcurrentHashMap (二)—— putVal)