java高并发(二十)HashMap与ConcurrentHashMap

HashMap

e17089bd87ce4bc475802700b82338d35bf.jpg

HashMap底层就是一个数组,而数组的每一项都是一个链表,当我们新建一个HashMap时就会初始化一个数组。HashMap有两个参数影响性能,分别是初始容量和加载因子。 

HashMap寻址方式:对于一个新插入的数据或者需要读取的数据,HashMap需要根据key按照一个计算规则计算出Hash值并对我们的数组长度进行取模,取模结果作为数组的index,而取模的代价远远高于位运算的代价,因此HashMap的数组长度必须是2的N次方,将计算出的Hash值和2的N-1次方进行“与”运算,结果与取模操作是相同的。

HashMap并不要求用户在指定HashMap容量时必须传入一个2的N次方的整数,而是在初始化时根据传入的容量值计算出一个满足2的N次方的容量。

总所周知HashMap不是一个线程安全的,主要体现在执行resize方法时可能会产生死循环,当HashMap的size超过他的容量*负载因子时,就需要对HashMap扩容,具体方法是创建一个新的原来容量的两倍的数组(保证新的容量仍然是2的N次方,从而保证上述的寻址方式仍然适用),同时把原来的数组重新插入到新的数组中,这一过程并不保证线程安全,而且在多线程并发调用时可能会产生死循环。

9782ff79b8a58f9398aa66085a60821044f.jpg

上面是单线程下reHash的扩容步骤。

在多线程情况下:

8fd9b66eb1d7cae4d28bd3fa3b6a41ccfe3.jpg

ConcurrentHashMap

数据结构:

df454025add84fc41b110c1d3998af1e3fe.jpg

c1d6a6101aec8b12415d9794ada0716a9f4.jpg

使用了红黑树来提高性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值