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 锁。

 

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

 初始化参数

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

posted @ 2020-11-16 16:28  byebai95  阅读(125)  评论(1编辑  收藏  举报