Toc
  1. 如何保证线程安全
  2. 重要属性
    1. sizeCtl
  3. 扩容
    1. 扩容步骤
    2. 扩容中并发读写的处理
  4. 好文章
  5. 待整理
Toc
0 results found
BOBO
ConcurrentHashMap
2020/08/24 Java基础

如何保证线程安全

1.7 通过 Segement 可重入的分段锁
1.8 元素链表头节点 CAS 实现锁分离;volatile 修饰 table 和 sizeCtl 属性保证线程可见

重要属性

sizeCtl

默认为 0,用来控制 table 的初始化和扩容操作
-1  代表 table 正在初始化
-N  表示有 N-1 个线程正在进行扩容操作  
如果 table 未初始化,表示 table 需要初始化的大小。
如果 table 初始化完成,表示 table 的容量,默认是 table 大小的 0.75 倍

扩容

扩容步骤

1、通过 CPU 核心数和数组长度计算每个线程负责迁移的桶个数,最小为 16。线程数量如何确定?
2、初始化 nextTable,将原 table 容量增加一倍。
3、将原 table 链表或者红黑树中的元素分为高位链和低位链,然后将链表移动到 n+1 位置上去。
4、最后一个扩容线程会负责重新检查一遍数组查看是否有遗漏的桶

扩容中并发读写的处理

1、对于 get 读操作,如果当前节点有数据,还没迁移完成,此时不影响读,能够正常进行。如果当前链表已经迁移完成,那么头节点会被设置成 fwd 节点,此时 get 线程会帮助扩容。
2、对于 put/remove 写操作,如果当前链表已经迁移完成,那么头节点会被设置成 fwd 节点,此时写线程会帮助扩容,如果扩容没有完成,当前链表的头节点会被锁住,所以写线程会被阻塞,直到扩容完成。

好文章

ConcurrentHashMap1.8 - 扩容详解 CSDN
ConcurrentHashMap 方法属性分析 掘金

待整理

1、扩容过程中的线程数变更和线程分配的桶如何变更
2、高位链低位链的生成和迁移过程

支付宝
微信
Simple is Awesome