ConcurrentHashMap 类注释
- 所有的操作都是线程安全的,我们在使用时,无需再加锁;
- 多个线程同时进行 put、remove 等操作时并不会阻塞,可以同时进行,和 HashTable 不同,
HashTable 在操作时,会锁住整个 Map; - 迭代过程中,即使 Map 结构被修改,也不会抛 ConcurrentModificationException 异常;
- 除了数组 + 链表 + 红黑树的基本结构外,新增了转移节点,是为了保证扩容时的线程安全的
节点; - 提供了很多 Stream 流式方法,比如说:forEach、search、reduce 等等。
ConcurrentHashMap 和 HashMap 两者区别
相同之处:
- 数组、链表结构几乎相同,所以底层对数据结构的操作思路是相同的(只是思路相同,底层实现不同);
- 都实现了 Map 接口,继承了 AbstractMap 抽象类,所以大多数的方法也都是相同的,HashMap 有的方法,ConcurrentHashMap 几乎都有,所以当我们需要从 HashMap 切换到ConcurrentHashMap 时,无需关心两者之间的兼容问题。
不同之处:
- 红黑树结构略有不同,HashMap 的红黑树中的节点叫做 TreeNode,TreeNode 不仅仅有属性,还维护着红黑树的结构,比如说查找,新增等等;ConcurrentHashMap 中红黑树被拆分成两块,TreeNode 仅仅维护的属性和查找功能,新增了 TreeBin,来维护红黑树结构,并负责根节点的加锁和解锁;
- 新增 ForwardingNode (转移)节点,扩容的时候会使用到,通过使用该节点,来保证扩容时的线程安全。
Put方法
- 如果数组为空,初始化,初始化完成之后,走 2;
- 计算当前槽点有没有值,没有值的话,cas 创建
casTabAt(tab, i, null, new Node<K,V>(hash, key, value, null))
,失败继续自旋(for 死循环),直到成功&#