concurrentHashMap实现原理

JDK6与JDK7中的实现:
理解concurrentHashMap首先最关键先理解一个概念:segment
segment是什么呢?segment自己就至关于一个HashMap对象,同时又继承了ReentrantLock;同HashMap同样,segment包含一个HashEntry数组,数组的每个HashEntry既是一个键值对,也是一个链表的头节点;HashEntry中的value和next都被volatile修饰,用于多线程保证可见性。
像这样的segment对象,在concurrentHashMap中集合中有2的N次方个,共同保存在一个名为segments的数组当中。
 
所以整个ConcurrentHashMap的结构以下:
concurrentHashMap是在一个总的哈希表下面,有若干个子哈希表。这样的二级结构,数据库的水平拆分有些类似。
这样设计的优点在于:才用了锁分段技术,每个segment就比如一个自治区,读写操做高度自治,segment之间互不影响。
不一样segment的写入能够并发执行,同一个segment的读写能够并发执行,同一个segment的并发写会被阻塞。因而可知,concurrentHashMap当中每一个segment各自持有一把锁。在保证线程安全的同时下降了锁的粒度,让并发操做效率更高。
ConcurrentHashMap的读写详细过程:
Get方法:
1.为输入的key作hash运算,获得hash值
2.经过hash值,定位到对应的segment对象
3.再次经过hash值,定位到segment当中数组的具体位置
Put方法:
1.为输入的key作Hash运算,获得hash值
2.经过hash值,定位到对应的segment对象
3.获取可重入锁
4.再次经过hash值,定位到segment当中的数组的具体位置
5.插入活覆盖hashEntity对象
6.释放锁
 
ConcurrentHashMap的size方法是一个嵌套循环,答题逻辑以下:
1.遍历全部segment
2.把segment的元素数量累加起来
3.再一次把segment的元素数量累加起来
4.判断这一次与上一次统计的是否一致,不一致,从新统计,尝试次数+1;若是不是,说明没有修改,统计结束
5.若是尝试次数超过了阈值,则对每个segment加锁,再从新统计
6.再次判断全部segment的总修改次数是否大于上一次的总修改次数;因为已经加锁,次数必定和上次相等
7.释放锁,统计结束
 
ConcurrentHashMap在对Key求Hash值的时候,为了实现Segment均匀分布,进行了两次Hash。
 
并发度的概念:
  能够理解为:可以同时跟新ConcurrentHashMap且不产生锁竞争的最大线程数,实际上就是ConcurrentHashMap的分段锁个数,即Segment[]数组的长度。

rehash的概念:
    相对于HashMap的resize,ConcurrentHashMap的rehash原理相似,可是作了必定的优化,避免让全部的节点都进行复制操做:因为扩容是基于2的幂指来操做,假设扩容前某HashEntry对应到Segment中数组的index为i,数组的容量为capacity,那么扩容后该HashEntry对应到新数组中的index只可能为i或者i+capacity,所以大多数HashEntry节点在扩容先后index能够保持不变。基于此,rehash方法中会定位第一个后续全部节点在扩容后index都保持不变的节点,而后将这个节点以前的全部节点重排便可。

node

ConcurrentHashMap是弱一致性,get到的数据多是过期的。ConcurrentHashMap不容许key或者value为null。算法

JDK8中的实现:数据库

  摒弃了Segment分段锁的概念,启用了CAS算法,底层依然由 “数组” + 链表 + 红黑树的方式;为了并发,添加了例如:TreeBin、Traverser等内部对象类。数组

  sizeCtl属性:负值表明正在进行初始化或者扩容,-1表明正在初始化 ,-N表明有N-1个线程正在扩容;正数或者0表明hash表尚未被初始化,这个值标识初始化或者下一次扩容的大小,始终未ConcurrentHashMap容量的0.75倍,与loadfactor对应。安全

  不采用segment而采用node,锁住node来实现减少锁粒度。
  设计了MOVED状态 当resize的中过程当中 线程2还在put数据,线程2会帮助resize。
  使用3个CAS操做来确保node的一些操做的原子性,这种方式代替了锁。
  sizeCtl的不一样值来表明不一样含义,起到了控制的做用。

多线程

相关文章
相关标签/搜索