HashMap(常见面试问题汇总)-头插法为啥产生环形了呢?为啥使用扰动函数?ConcurrentHashMap的分段锁的实现原理是什么?

**

1,头插法产生闭环的根本原因

什么是头插法:即next数据指向新数组节点,在新数组看来是插到了头部位置
**
在这里插入图片描述
在这里插入图片描述
主要发生环形就是因为这段代码:e.next = newTable[i],这个代码主要就是将数组二得数据放到了数组一节点新遍历的数据下面,代码表示就是,先把b赋值到新数组,然后找到c,把c的指针指向了新数组即b,那边其他线程进入该方法时,新线程在处理数组一的c节点时next就是b,而b的next也指向了c,形成环形

2、为啥使用扰动函数

什么是扰动函数:即hash方法
扰动函数是拿key的hashcode值和值的高16位进行亦或运算,降低碰撞几率,hashcode方法返回的int类型的散列数据
,大概有-21亿到21亿之间,数据非常大,但是在取数组下标时使用低位掩码,如默认hashmap数组长度16,则低位采用15,0000 0000 0000 000 1111 进行&运算,最后只取后四位,为了降低后四位的重复几率,采用高16位异或计算,打破低位重复规律

bucketIndex = indexFor(hash, table.length);

static int indexFor(int h, int length) {
     return h & (length-1);
}

在这里插入图片描述

3、ConcurrentHashMap的分段锁的实现原理

首先分段锁是在1.7版本中,使用segment,ConcurrentHashMap中存放的数据是一段段的,即由多个Segment(段)组成的。每个Segment中都有着类似于数组加链表的结构。
static final class Segment<K,V> extends ReentrantLock implements Serializable

在这里插入图片描述

Segment继承了ReentrantLock,表明每个segment都可以当做一个锁
分段锁的优势在于保证在操作不同段 map 的时候可以并发执行,但是如果某段过大时会导致性能下降

1.8版本抛弃了分段锁,采用cas+synchonized,将锁对象细化到节点,同时使用cas乐观锁
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值