0%

concurrenthashmap

①, 重要的常量:
private transient volatile int sizeCtl;
当为负数时, -1 表示正在初始化, -N 表示 N - 1 个线程正在进行扩容;
当为 0 时, 表示 table 还没有初始化;
当为其他正数时, 表示初始化或者下一次进行扩容的大小.

②, 数据结构:
Node 是存储结构的基本单元, 继承 HashMap 中的 Entry, 用于存储数据;
TreeNode 继承 Node, 但是数据结构换成了二叉树结构, 是红黑树的存储结构, 用于红黑树中存储数据;
TreeBin 是封装 TreeNode 的容器, 提供转换红黑树的一些条件和锁的控制.

③, 存储对象时 (put() 方法) :
1.如果没有初始化, 就调用 initTable() 方法来进行初始化;
2.如果没有 hash 冲突就直接 CAS 无锁插入;
3.如果需要扩容, 就先进行扩容;
4.如果存在 hash 冲突, 就加锁来保证线程安全, 两种情况: 一种是链表形式就直接遍历到尾端插入, 一种是红黑树就按照红黑树结构插入;
5.如果该链表的数量大于阀值 8, 就要先转换成红黑树的结构, break 再一次进入循环
6.如果添加成功就调用 addCount() 方法统计 size, 并且检查是否需要扩容.

④, 扩容方法 transfer(): 默认容量为 16, 扩容时, 容量变为原来的两倍.
helpTransfer(): 调用多个工作线程一起帮助进行扩容, 这样的效率就会更高.

⑤, 获取对象时 (get()方法) :
1.计算 hash 值, 定位到该 table 索引位置, 如果是首结点符合就返回;
2.如果遇到扩容时, 会调用标记正在扩容结点 ForwardingNode.find()方法, 查找该结点, 匹配就返回;
3.以上都不符合的话, 就往下遍历结点, 匹配就返回, 否则最后就返回 null.

1. Tode

  • 阅读源码

2. Resource