Collections之Map&List&Set详

HashMap数据结构数组+链表+(红黑树jdk>=8)源码原理分析重要成员变量DEFAULT_INITIAL_CAPACITY=1<<4;Hash表默认初始容量MAXIMUM_CAPACITY=1<<30;最大Hash表容量DEFAULT_LOAD_FACTOR=0.75f;默认加载因子TREEIFY_THRESHOLD=8;链表转红黑树阈值UNTREEIFY_THRESHOLD=6;红黑树转链表阈值MIN_TREEIFY_CAPACITY=64;链表转红黑树时hash表最小容量阈值,达不到优先扩容。内部的执行机制源码见课堂讲解。HashMap是线程不安全的,不安全的具体原因就是在高并发场景下,扩容可能产生死锁(Jdk1.7存在)以及get操作可能带来的数据丢失。Jdk7-扩容死锁分析死锁问题核心在于下面代码,多线程扩容导致形成的链表环
在这里插入图片描述
ConcurrentHashMap数据结构ConcurrentHashMap的数据结构与HashMap基本类似,区别在于:1、内部在数据写入时加了同步机制(分段锁)保证线程安全,读操作是无锁操作;2、扩容时老数据的转移是并发执行的,这样扩容的效率更高
并发安全控制Java7ConcurrentHashMap基于ReentrantLock实现分段锁

并发安全控制Java7ConcurrentHashMap基于ReentrantLock实现分段锁

在这里插入图片描述
并发安全控制Java7ConcurrentHashMap基于ReentrantLock实现分段锁Java8中ConcurrentHashMap基于分段锁+CAS保证线程安全,分段锁基于synchronized关键字实现

在这里插入图片描述
重要成员变量ConcurrentHashMap拥有出色的性能,在真正掌握内部结构时,先要掌握比较重要的成员:LOAD_FACTOR:负载因子,默认75%,当table使用率达到75%时,为减少table的hash碰撞,tabel长度将扩容一倍。负载因子计算:元素总个数%table.lenghTREEIFY_THRESHOLD:默认8,当链表长度达到8时,将结构转变为红黑树。UNTREEIFY_THRESHOLD:默认6,红黑树转变为链表的阈值。MIN_TRANSFER_STRIDE:默认16,table扩容时,每个线程最少迁移table的槽位个数。MOVED:值为-1,当Node.hash为MOVED时,代表着table正在扩容TREEBIN,置为-2,代表此元素后接红黑树。nextTable:table迁移过程临时变量,在迁移过程中将元素全部迁移到nextTable上。sizeCtl:用来标志table初始化和扩容的,不同的取值代表着不同的含义:0:table还没有被初始化-1:table正在初始化小于-1:实际值为resizeStamp(n)<<RESIZE_STAMP_SHIFT+2,表明table正在扩容大于0:初始化完成后,代表table最大存放元素的个数,默认为0.75*ntransferIndex:table容量从n扩到2n时,是从索引n->1的元素开始迁移,transferIndex代表当前已经迁移的元素下标ForwardingNode:一个特殊的Node节点,其hashcode=MOVED,代表着此时table正在做扩容操作。扩容期间,若table某个元素为null,那么该元素设置为ForwardingNode,当下个线程向这个元素插入数据时,检查hashcode=MOVED,就会帮着扩容。ConcurrentHashMap由三部分构成,table+链表+红黑树,其中table是一个数组,既然是数组,必须要在使用时确定数组的大小,当table存放的元素过多时,就需要扩容,以减少碰撞发生次数,本文就讲解扩容的过程。扩容检查主要发生在插入元素(putVal())的过程:一个线程插完元素后,检查table使用率,若超过阈值,调用transfer进行扩容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术学习分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值