2022.08.30 学习笔记

ConcurrentHashMap

HashTable

实现了同步操作,但是由于其实现的是使用了synchronized关键字对put等操作进行加锁,而synchronized关键字加锁是对整个对象进行加锁,也就是说在进行put等修改Hash表的操作时,锁住了整个Hash表,从而使得其表现的效率低下。

JDK 1.7

Java使用了分段锁机制实现ConcurrentHashMap

ConcurrentHashMap在对象中保存了一个Segment数组,即将整个Hash表划分为多个分段;而每个Segment元素,即每个分段则类似于一个Hashtable;这样,在执行put操作时首先根据hash算法定位到元素属于哪个Segment,然后对该Segment加锁即可。因此,ConcurrentHashMap在多线程并发编程中可是实现多线程put操作。

在这里插入图片描述

concurrencyLevel: 并行级别、并发数、Segment 数,默认是 16,也就是说 ConcurrentHashMap 有 16 个 Segments,所以理论上,这个时候,最多可以同时支持 16 个线程并发写,只要它们的操作分别分布在不同的 Segment 上。这个值可以在初始化的时候设置为其他值,但是一旦初始化以后,它是不可以扩容的。

  • initialCapacity: 初始容量,这个值指的是整个 ConcurrentHashMap 的初始容量,实际操作的时候需要平均分给每个 Segment。

  • loadFactor: 负载因子,之前我们说了,Segment 数组不可以扩容,所以这个负载因子是给每个 Segment 内部使用的。

  • 用 new ConcurrentHashMap() 无参构造函数进行初始化的,那么初始化完成后:

    • Segment 数组长度为 16,不可以扩容
    • Segment[i] 的默认大小为 2,负载因子是 0.75,得出初始阈值为 1.5,也就是以后插入第一个元素不会触发扩容,插入第二个会进行第一次扩容
    • 这里初始化了 segment[0],其他位置还是 null,初始化segment[0]是为了使用当前 segment[0] 处的数组长度和负载因子来初始化 segment[k]。ensureSegment(int k) 用于初始化槽,对于并发操作使用 CAS(Compare and Swap ,即 比较和替换) 进行控制。
    • 当前 segmentShift 的值为 32 - 4 = 28,segmentMask 为 16 - 1 = 15,姑且把它们简单翻译为移位数和掩码
  • 获取写入锁: scanAndLockForPut:一个是 tryLock() 成功了,循环终止,另一个就是重试次数超过了 MAX_SCAN_RETRIES,进到 lock() 方法,此方法会阻塞等待,直到成功拿到独占锁。---->获取该 segment 的独占锁

  • get:计算 hash 值,找到 segment 数组中的具体位置,到这里是链表了,顺着链表进行查找即可

CAS

CAS全称compare and swap——比较并替换,它是并发条件下修改数据的一种机制,包含三个操作数:

  • 需要修改的数据的内存地址(V);
  • 对这个数据的旧预期值(A);
  • 需要将它修改为的值(B);

CAS的操作步骤如下:

  1. 修改前记录数据的内存地址V;
  2. 读取数据的当前的值,记录为A;
  3. 计算要修改为的值B;
  4. 查看地址V下的值是否仍然为A,若为A,则用B替换它;若地址V下的值不为A,表示在自己修改的过程中,其他的线程对数据进行了修改,则不更新变量的值,而是重新从步骤2开始执行,这被称为自旋;

参考链接:https://pdai.tech/md/java/thread/java-thread-x-juc-collection-ConcurrentHashMap.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值