当前位置: 首页 > news >正文

比HashTable更先进的ConcurrentHashMap及其多线程协助扩容机制

HashTable是1996年1月(我还没出生尼)Java1.0时期就开始推出的一款存储key-value类型数据的集合,彼时HashMap还没有被造出来。HashTable继承自抽象类Dictionary,它也是一个过时的遗留类,之所以没被从jdk中移除,是因为考虑到历史项目的兼容性问题。倘若移除的话,那些已经使用了Dictionary的所有项目都需要重构这部分代码,影响实在是太大了。对于我们开发者来说,我们尽量不要使用它就是了。取而代之的是更先进的Map interface和HashMap,Map interface也是后来引入的。

HashTable并发访问时效率太低了,所以才被淘汰了。因为它的get()、put()都带有synchronized修饰符,这就导致同一时间,只能有一个线程访问这个集合,性能实在令人堪忧。相比之下,jdk8版本中的ConcurrentHashMap并发访问的效率就大大提高了。它之所以高效是因为其会在存储桶级别加锁,例如a、b线程可以分别并发访问1、2两个存储桶中的key-value数据,互不影响。

下图是Doug Lea,ConcurrentHashMap的创始人,中文名为道格·利。美国国籍,现担任纽约州立大学Oswego分校教师。
ConcurrentHashMap的创始人Doug Lea

多线程协助扩容机制

ConcurrentHashMap的存储桶是Node类型的对象,遇到扩容时,假如A存储桶中的节点已经被迁移到新的数组后,在老数组中的Node类会被替换为ForwardingNode这个子类,这样一来,等其它线程要访问A存储桶中的key-value时,有如下两种情形:

如果发现节点类型是ForwardingNode,就明白了当前Map正在进行扩容操作,并且当前这个存储桶中的节点已经被完全迁移到新数组了,于是它就会暂时放弃读取数据的任务,先帮着一起迁移数据到新数组,等所有key-value都迁移到新数组后,就会继续执行读取数据的任务,只不过会从新数组中读取了。

如果发现节点类型是Node类,那它就知道这个存储桶中的key-value还都没被迁移走呢,那它就可以无视正在进行的扩容操作,继续自顾自地执行访问数据的任务即可。

相关文章:

  • 汇编常用语法
  • Spring的数据库编程
  • Linux:web服务
  • Warp调度器:藏在显卡里的时间管理大师
  • 【vue3】黑马程序员前端Vue3小兔鲜电商项目【八】
  • Flowable7.x学习笔记(十九)归还我的待办
  • ARM寻址方式
  • 【时时三省】(C语言基础)怎样定义和引用一维数组
  • 【Redis】Redis常用命令
  • 排序功法入门指南【江湖算法笔记】
  • 13.Excel:分列
  • 【论文阅读】LLMOPT:一种提升优化泛化能力的统一学习框架
  • Cona编译问题
  • 工程师 - What is EMF?
  • 工程师 - 小米汽车尾部主动扩散器
  • 文章记单词 | 第64篇(六级)
  • 湖仓一体架构解析:如何平衡数据灵活性与分析性能?
  • 五一作业-day01
  • 从入门到登峰-嵌入式Tracker定位算法全景之旅 Part 3 |混合定位实战:Wi-Fi RTT / LoRa / BLE RSSI AoA 多源融合
  • Python3与Dubbo3.1通讯解决方案(dubbo-python)
  • 马丽称不会与沈腾终止合作,“他是我的恩人,也是我的贵人”
  • 习近平将对俄罗斯进行国事访问并出席纪念苏联伟大卫国战争胜利80周年庆典
  • 金正恩视察重要坦克厂并强调更迭陆军装备
  • 保持高位运行,今天全国铁路预计发送旅客1800万人次
  • 全国共有共青团员7531.8万名,共青团组织439.7万个
  • 申活观察|咖香涌动北外滩,带来哪些消费新想象?