ConcurrentHashMap 整理

HashMap 线程不安全,在多线程的情况下,可能会造成死循环,导致cpu 利用率低下

HashTable 线程安全,但是效率低下,使用synchronized 保证线程安全(put /get 都有锁)

解决办法

HashTable 容器在竞争激烈的情况出现低效率的原因是:所有访问HashTable 的线程都竞争同一把锁,假如容器有多把锁,每一把锁用于锁容器中一部分数据,那么多线程访问容器里不同段的数据时,线程间就不会存在竞争锁。

 可以有效的提高效率,ConcurrentHashMap 使用的就是锁分段技术。

ConcurrentHashMap 是由 Segment 数组结构和 HashEntity 数组结构组成。Segment 是一种可重入锁 ReentrantLock ,在ConcurrentHashMap 里扮演锁的角色,HashEntity 则用于存储键值对数据。一个ConcurrentHashMap 里包含

一个Segment 数组,Segment 的结构与hashMap 类似,是一种数组和链表结构。一个Segment 里包含一个HashEntity 数组,每隔HashEntity 是一个链表结构的元素,每个Segment 守护着一个HashEntity 数组里的元素,当对HashEntity

数组进行修改时,必须首先获得它对应的Segment 锁。

ConcurrentHashMap 整理

 JDK 1.8 的实现抛弃了Segment 分段锁机制,采用了 CAS + Synchronized 来保证并发更新的安全。数据结构采用:数组+链表+红黑树

ConcurrentHashMap 整理

 初始化参数

private static final int MAXIMUM_CAPACITY = 1 << 30;

private static final int DEFAULT_CAPACITY = 16;

static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

private static final float LOAD_FACTOR = 0.75f;

static final int TREEIFY_THRESHOLD = 8;

static final int UNTREEIFY_THRESHOLD = 6;

 table 扩容

当table 容量不足时,需要进行扩容,整个扩容分为两部分:

  1. 构建一个nextTable ,大小为table 的两倍
  2. 把table 的数据复制到nextTable 中

参考 : https://www.jianshu.com/p/d0b37b927c48