java面试 – ConcurrentHashMap的扩容机制

1.7版

ReentrantLock+Segment+hadEntry,一个Segment中包含一个HashEntry数组,每个HashEntry又是一个链表结构

元素查询:二次Hash,第一次Hash定位到Segment,第二次Hash定位到元素所在链表头部

锁:Segment分段锁,继承了ReentrantLock,锁定操作的Segment,其它Segment不受影响,并发度为Segment个数,可通过构造函数指定,数据扩容不会影响到其它Segment,get方法无需加锁,volatile保证

1.基于segment分段实现

2.每个segment相对于一个小型的HashMap

3.每个segment内部都会进行扩容,与HashMap扩容类似

4.先生成新的数组,然后转移元素到新数组中

5.扩容的判断也是每个segment内部单独判断,是否超过阀值

 

1.8版:

synchronized+CAS+Node+红黑树,Node的val和next都用volatile保证可见性

查找,替换,赋值操作都使用CAS

锁:锁链表的head节点,不影响其它元素读写,锁粒度更细,效率更高,扩容时,阻塞所有的读写操作,并发扩容

读操作无损:Node的val和next使用volatile修饰,多线程可见,数组用volatile修饰,保证扩容时被读线程感知

1.不再基于segment实现

2.当线程进行put时,如果CurrentHashMap正在进行扩容,那么该线程一起扩容

3.当线程进行put时,如果CurrentHashMap未正在扩容,则将key-value添加到ConcurrentHashMap中,然后判断是否超过阀值,过了则进行扩容

4.ConcurrentHashMap支持多个线程同时进行扩容

5.扩容之前也是先生成一个数组

6.在转移元素时,先将原数组分组,将分组交给不同的线程进行元素转移,每个线程对一组或多组元素转移

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享