ConcurrentHashMap
ConcurrentHashMap相当于线程安全的HashMap。
JDK1.7
ConcurrengtHashMap在1.7版本中使用了分段锁(Segmented Locks)数组 + HashEntry数组的组合。它将整个数据集划分为多个段(Segment),每个段都有一个独立的锁。每个段内部使用一个HashEntry数组来存储键值对。其中HashEntry是一条链表,当对某个 HashEntry 数组中的元素进行修改时,必须首先获得该元素所属 HashEntry 数组对应的 Segment 锁。
可以理解成Segment有多少个元素就意味着允许多少个线程同时执行
put()操作:先通过Hash算法定位Segment,再尝试获取锁(失败重试),插入前判断Segment是否需要扩容,最后才是对应位置的元素插入/修改。
JDK1.8
ConcurrengtHashMap在1.8版本中使用了Node数组(每个Node是一个链表结构,并且可以树化成红黑树)+CAS+Synchronized来保证并发安全进行实现。
put()操作:通过hashCode定位Node节点(以下为if-elseIf判断顺序)
①数组未初始化会先进行初始化。
②判断table中是否含有相同的key,如果没有就通过CAS去进行新增操作(无锁)
③判断是否需要扩容,需要则协助扩容
④最后如果table不为空,key也不为null(有重复),则利用 synchronized 锁写入数据,这是唯一一处加锁的地方
图片资料取自concurrenthashmap实现原理_concurrenthashmap的实现原理_Laflame_official的博客-优快云博客