面试题12-ConcurrentHashMap

ConcurrentHashMap原理及jdk7和jdk8的区别

jdk7:

  • 数据结构:

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

  • 元素查询:

二次hash,第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部

  • 锁:

Segment分段锁 Segment继承了ReentrantLock,锁定操作的Segemnt,其他的Segment不受影响,并发度为segment个数,可以通过构造函数指定,数组扩容不会影响到其他的Segment

  • get方法无需加锁,volatile保证。

jdk8:

  • 数据结构:

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

  • 元素查询,替换,复制操作都使用CAS。
  • 锁:锁链表的head节点,不影响其他元素的读写,锁粒度更细,效率更高,扩容时,阻塞所有的读写操作、并发扩容
  • 读操作无锁:
    • Node的val和next使用volatile修饰,读写线程对该变量互相可见。
    • 数组用volatile修饰,保证扩容时被读线程感知

CAS

https://segmentfault.com/a/1190000014858404

CAS 全称是 compare and swap,是一种用于在多线程环境下实现同步功能的机制。CAS 操作包含三个操作数 -- 内存位置、预期数值和新值。CAS 的实现逻辑是将内存位置处的数值与预期数值想比较,若相等,则将内存位置处的值替换为新值。若不相等,则不做任何操作。

在 Java 中,Java 并没有直接实现 CAS,CAS 相关的实现是通过 C++ 内联汇编的形式实现的。Java 代码需通过 JNI 才能调用。关于实现上的细节,我将会在第3章进行分析。

前面说了 CAS 操作的流程,并不是很难。但仅有上面的说明还不够,接下来我将会再介绍一点其他的背景知识。有这些背景知识,才能更好的理解后续的内容。

原文地址:https://www.cnblogs.com/jsit-dj-it/p/15478614.html