ConcurrentHashMap(JDK1.8) 总结

put流程

和HashMap 一样, 首先会对Hash做一次散列
之后进入循环, 和HashMap一样,如果Node数组为空, 会先对Node数组进行初始化, 这里为了保证数组不被重复初始化, 同样采用了循环 + CAS 的方式


DeepinScrot-3923.png

这里sizeCtl是用于控制Node数组resize和init的变量, 当sizeCtl为-1 时, 则标识其为正在创建的状态, 在这里, table, sizeCtl 都有violate 修饰符, 用于保证多线程中 变量的可见性

之后, 会检查数组对应index的值是否为空, 若为空, 则同样通过CAS对数组对应位置进行赋值


DeepinScrot-4726.png

若此时正处于resize状态, 则协助进行resize
否则, 则会对bin中的第一个节点加锁, 之后流程与HashMap一致, 在完成put之后, 会判断当前bin的长度, 当长度大于8(树化阈值)时会将链表转树
在树化一个bin时, 首先会判断数组的长度是否超过了MIN_TREEIFY_CAPACITY(64), 若没有,则改为扩容


DeepinScrot-0310.png

在这里, 同样会对bin中第一个节点加锁, 来保证同一时刻, 对用一个bin只有一个线程可执行树化操作, 注意这里在进入同步代码块时, 有重新获取了当前bin中的头结点, 若不同,则意味着另一个线程已经完成了树化操作, 可直接返回.
在这里TreeBin 为Node的子类, 它封装了TreeNode, 它指向TreeNode root 节点, 并对TreeNode 进行调整, 其hash为TreenBin (-2)

get流程

DeepinScrot-2516.png

这里取值流程与HashMap几乎一致
注意的是当eh为负时,意味着当前bin为树root节点

你可能感兴趣的:(ConcurrentHashMap(JDK1.8) 总结)