ConcurrentHashMap类继承至AbstractMap 实现接口ConcurrentMap,Serializable算法
这个类有如下主要的几个静态变量数组
DEFAULT_INITIAL_CAPACITY=16 初始化数组长度安全
DEFAULT_LOAD_FACTOR=0.75 默认装载因子并发
DEFAULT_CONCURRENCY_LEVEL=16 默认并发级别ssh
MAXIMUM_CAPACITY=1<<30 最大数组长 1<<30高并发
MIN_SEGMENT_TABLE_CAPACITY=2 最小桶长度 线程
MAX_SEGMENTS=1<<16 最大桶数量指针
接下来是ConcurrentHashMap的构造器对象
1.能够注意到其中的运算 sshift是并发级别的角标 注意 这里的concurrencyLevel是2的倍数继承
ssize能够近似看做是concurrencyLevel
2。建立了一个桶对象 s0,和一个桶的数组长度为ssize
这里的HashEntry结构如图
四个变量分别为 key,(volatile修饰保证内存可见性)value,key的hash值(hash) 还有一个用volatile变量修饰的HashEntry元素指针 指向下一个元素
桶segment的类结构以下
桶的主要元素 是一个HashEntry的数组变量和一切其余信息
因此 整个ConcurrentHashMap的结构是一个数组(segment)数组的每个元素仍是一个(HashEntry)数组
接下来看一下put方法
这里的seqmentShift是经过并发等级获得的值 并发等级为N
则segmentShift=32-a,这里得a=log2 N。2为底N为幂 的对数值
这里的J至关于取 他的key的hash值得高a位
经过ensureSegment方法去获取 hash值所在得桶segment对象 注意 在ConcurrentHashmap里面获取对象都是经过UNSAFE.getObjectVolatile去获取得 而且经过CAS(compareAndSwap)算法 去比较赋值 这是保证在高并发下数据保持一致得一种算法
CAS算法 是 有三个值 一个原始值K,一个修改值B,一个预估值A
在修改得时候 先比较原始值 和预估值(在预估值上进行计算获得修改值),当且这两个值相等的时候,才将修改值 写入内存
能够看到
1.加锁
2.调用桶 segment得put方法,经过拿到得桶对象,获取第一个HashEntry数组元素,依次往下遍历,第一个IF判断里是HashEntry[] 里有相同得Key值元素得时候 进行值替换操做 而且控制角标往数组下方移动
3.else里面则是当角标移动到数组最后一位得时候进行元素得新建操做
4.解锁
能够看到,整个ConcurrentHashMap是一个数组加数组加链表得结构
其中HashEntry 在内存上连续 在结构上经过index关联 而后经过next指针关联一串链表
在对每个桶(segment)操做得时候 对其中得HashEntry[](表结构)会进行加锁(trylock)和解锁(unlock)操做 这就是ConcurrentHashMap得分段锁机制。将每个桶单独作成一个HashMap结构 在高并发得时候 以表结构为单位进行操做。而且经过CAS算法 确保了数据得一致性。因此 ConcurrentHashMap相较于Hashtable而言是效率更高得 相对于HashMap而言 是线程安全得