首页 > 其他分享 >ConcurrentHashMap是如何实现线程安全的

ConcurrentHashMap是如何实现线程安全的

时间:2024-02-01 16:46:07浏览次数:32  
标签:Node 扩容 ConcurrentHashMap 并发 安全 线程

 

但是又为何需要学习ConcurrentHashMap?用不就完事了?我认为学习其源码有两个好处:

  1. 更灵活的运用ConcurrentHashMap
  2. 欣赏并发编程大师Doug Lea的作品,源码中有很多值得我们学习的并发思想,要意识到,线程安全不仅仅只是加锁
    ConcurrentHashMap是怎么做到线程安全的?

        get方法如何线程安全地获取key、value?
        put方法如何线程安全地设置key、value?
        size方法如果线程安全地获取容器容量?
        底层数据结构扩容时如果保证线程安全?
        初始化数据结构时如果保证线程安全?

    ConcurrentHashMap并发效率是如何提高的?

        和加锁相比较,为什么它比HashTable效率高?
    参考链接:https://blog.csdn.net/qq_41737716/article/details/90549847
                            
    程序中的可伸缩性(提升外部资源即可提升并发性能的比率)是由程序中串行执行部分所影响的,而常见的串行执行有锁竞争(上下文切换消耗、等待、串行)等等,这给了我们一个启发,可以通过减少锁竞争来优化并发性能,而ConcurrentHashMap则使用了锁分段(减小锁范围)、CAS(乐观锁,减小上下文切换开销,无阻塞)等等技

    相关概念

    Amdahl定律

    此节定律描述均来自《Java并发编程实战》一书

     

    假设F是必须被串行执行的部分,N代表处理器数量,Speedup代表加速比,可以简单理解为CPU使用率
    在这里插入图片描述
    此公式告诉我们,当N趋近无限大,加速比最大趋近于1/F;

    N越大,处理器越多,串行执行越少,cpu利用率越大
    初始化数据结构时的线程安全

    HashMap的底层数据结构这里简单带过一下,不做过多赘述:
    在这里插入图片描述
    大致是以一个Node对象数组来存放数据,Hash冲突时会形成Node链表,在链表长度超过8,Node数组超过64时会将链表结构转换为红黑树,Node对象:

     


    static class Node<K,V> implements Map.Entry<K,V> {
      final int hash;
      final K key;
      volatile V val;
      volatile Node<K,V> next;
      ...
    }

     

     总结

    就算有多个线程同时进行put操作,在初始化数组时使用了乐观锁CAS操作来决定到底是哪个线程有资格进行初始化,其他线程均只能等待。

    用到的并发技巧:

        volatile变量(sizeCtl):它是一个标记位,用来告诉其他线程这个坑位有没有人在,其线程间的可见性由volatile保证。
        CAS操作:CAS操作保证了设置sizeCtl标记位的原子性,保证了只有一个线程能设置成功

     

     

     

     由于其减小了锁的粒度,若Hash完美不冲突的情况下,可同时支持n个线程同时put操作,n为Node数组大小,在默认大小16下,可以支持最大同时16个线程无竞争同时操作且线程安全。当hash冲突严重时,Node链表越来越长,将导致严重的锁竞争,此时会进行扩容,将Node进行再散列,下面会介绍扩容的线程安全性。总结一下用到的并发技巧:

        减小锁粒度:将Node链表的头节点作为锁,若在默认大小16情况下,将有16把锁,大大减小了锁竞争(上下文切换),就像开头所说,将串行的部分最大化缩小,在理想情况下线程的put操作都为并行操作。同时直接锁住头节点,保证了线程安全
        Unsafe的getObjectVolatile方法:此方法确保获取到的值为最新

    扩容操作的线程安全

    在扩容时,ConcurrentHashMap支持多线程并发扩容,在扩容过程中同时支持get查数据,若有线程put数据,还会帮助一起扩容,这种无阻塞算法,将并行最大化的设计,堪称一绝。

    先来看看扩容代码实现:

    ConcurrentHashMap运用各类CAS操作,将扩容操作的并发性能实现最大化,在扩容过程中,就算有线程调用get查询方法,也可以安全的查询数据,若有线程进行put操作,还会协助扩容,利用sizeCtl标记位和各种volatile变量进行CAS操作达到多线程之间的通信、协助,在迁移过程中只锁一个Node节点,即保证了线程安全,又提高了并发性能。


    参考链接:https://blog.csdn.net/qq_41737716/article/details/90549847

标签:Node,扩容,ConcurrentHashMap,并发,安全,线程
From: https://www.cnblogs.com/JavaYuYin/p/18001581

相关文章

  • 【操作系统和计网从入门到深入】(八)线程
    复习八·线程1.如何理解线程只要满足,比进程轻量化,cpu内所有线程资源共享,创建维护成本更低等要求,就能叫线程。不同的OS实现方式不同,下面这个是Linux特有的方案。Linux没有给线程重新设计数据结构!什么叫做进程?pcb+地址空间+页表CPU调度的基本单位:线程!2.开始使用pthre......
  • U盘分区加密功能如何确保数据的安全性?
    在这个信息高度化、电子化的时代,数据的安全性是每个企业乃至个人都备受关注的问题。随着移动设备及其携带的数据量的增长,我们越来越需要一种安全、便捷的数据携带和传输方式。华企盾分区加密系统的U盘分区加密功能正是为此而生。其强大而灵活的加密技术,确保了我们在享受便携式设备......
  • 深入浅出Java多线程(五):线程间通信
    引言大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第五篇内容:线程间通信。大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!!在现代编程实践中,多线程技术是提高程序并发性能、优化系统资源利用率的关键手段。Java作为主流的多线程支持语言,不仅提供了丰富的......
  • 异构计算关键技术之多线程技术(三)
    异构计算关键技术之多线程技术(三)一、多线程概述1.多线程的概念与优劣多线程是指在程序中同时运行多个线程,每个线程都可以独立执行不同的代码段,且各个线程之间共享程序的数据空间和资源。优劣:优点:提高程序的处理能力,增加相应速度和交互性。缺点:线程的切换有一定的开销,且多线程容易......
  • [90G] 以太网交换机 VSC7549-V/5CC、VSC7549TSN-V/5CC-VAO、VSC7549TSN-V/5CC 提供差
    1、VSC7549-V/5CC 90GEnterpriseSwitch概述VSC7549SPARX-5-90是一款90GbpsSMB/SME以太网交换机,支持1G、2.5G、5G和10G以太网端口组合。该设备提供了一组丰富的企业以太网交换功能。它使用多级多功能内容感知处理器(VCAP)技术,提供VLAN和QoS处理,通过智能帧处理和灵活的帧操作......
  • 数据安全防泄密解决方案 - 如何保护企业敏感信息?
    在当今这个数字化时代,企业敏感信息的安全成为公司运营的重中之重。如何确保贵司的研发数据、商业秘密和客户资料不落入竞争对手的手中?华企盾DSC数据安全解决方案提供了一系列综合手段,帮助企业实现敏感信息的有效保护。动态文件加密与实时监控采用动态加密技术确保所有文件在存储......
  • 【渗透工具】一款自动化分析网络安全应急响应工具--FindAll
    简介这款工具的推出将极大地提升蓝队应对网络安全事件的能力,不仅有助于提高响应效率,还能够降低工作复杂性。通过提供全面的信息搜集和高效的威胁分析,我们可以帮助蓝队成员在复杂的网络环境中保持优势,但应急响应是一个十分复杂的工作此工具只能帮助蓝队人员收集部分信息,如有异常发......
  • 政府单位如何选择高效的安全数据交换系统?关键看4点
    政府作为我国重要组织单位,数据安全性至关重要,为了保障网络和数据安全,政府内部一般通过物理隔离或逻辑隔离的方式,因此,政府单位进行文件交换具有一定的特殊要求。一般来说,常见的政府内部文件交换工具有以下几种:电子公文传输系统:这是政府内部常用的一种文件交换工具,通过该系统,政府部......
  • DOCKER安全及日志管理
    DOCKER安全及日志管理容器的安全性问题的根源在于容器和宿主机共享内核。如果容器里的应用导致Linux内核崩溃,那么整个系统可能都会崩溃。与虚拟机是不同的,虚拟机并没有与主机共享内核,虚拟机崩溃一般不会导致宿主机崩溃。 Docker架构缺陷与安全机制1.容器之间的局域网攻击......
  • 浏览器支持多线程下载,IDM还是地表最强吗?
    引言平时大家下载小文件一般会用浏览器自带的下载,而大文件却要搭配下载器(比如有亿点点贵的IDM),但是大家知道吗,我们的浏览器自带多线程下载,只是默认是禁用的,试了试真的还不错!启动新功能这里以新版MicrosoftEdge为例,打开edge://flags/#enable-parallel-downloading(Chrome为c......