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

Java集合详解:ConcurrentSkipListMap

1. ConcurrentSkipListMap简介

  并发跳跃映射表 java.util.concurrent.ConcurrentSkipListMap,是一种可扩展高并发的有序映射表实现。ConcurrentSkipListMap 根据键大小进行排序,键可以通过 ConcurrentSkipListMap 的成员 Comparator 比较大小,如果 ConcurrentSkipListMap 没有注册比较器 Comparator,那么就需要键是可比较的(可比较的意思是键的类实现了 java.lang.Comparable 接口)。
  ConcurrentSkipListMap 实现了并发的 SkipList(跳表),不但提供了平均时间复杂度为 log(n) 的映射表基本操作,并且保证了在多线程环境下,插入、移除、更新,读取等并发操作的安全执行。
  ConcurrentSkipListMap 的并发遍历读操作只支持弱一致性,这是因为在遍历过程中,ConcurrentSkipListMap 的迭代器每次都只会返回键值对的不可变快照给读线程。顺序遍历的速度比逆序遍历的速度要快
  ConcurrentSkipListMapsize() 方法与其他的集合类不同,因为 ConcurrentSkipListMap 的异步性质,size() 方法需要遍历所有元素才能统计出结点个数,在并发环境下,可能会出现 size() 方法执行期间,跳表被其他线程修改的情况,因此 size() 方法返回的结果并不精确。
  ConcurrentSkipListMap 的批量操作比如 putAllequalstoArraycontainsValueclear 等方法,都不保证执行是原子的。比如读线程在使用迭代器对 ConcurrentSkipListMap 进行遍历的同时,写线程通过 putAll 方法向跳表中插入了一系列元素,那么读线程可能只会看到部分新增加的元素。
  ConcurrentSkipListMap 和其他并发类集合一样,不允许使用空键和空值(就是用 null作为键或者值),这是因为,在并发环境下,没有办法准确的区分 null 值与元素缺失。

2. ConcurrentSkipListMap 中的跳表

  ConcurrentSkipListMap 实现了一个 tree-like two-dimensionally linked skip list 就是树状二维链式跳表,索引等级和数据由不同类型的结点来表示。跳表全称为跳跃链表,本质是一个多层链表,它允许以平均时间复杂度 O(logn) 对一个有序链表执行查询,插入和删除操作。快速查询是通过维护一个多层次的链表,最底层是元素链表,元素链表上层是索引链表,索引链表中的每两个结点,都对应着其下层链表一个区间的边界(图1是一个具有2级索引的跳表)。一开始时,算法在最上层进行搜索,找到需要查找的元素所在的区间,这时,算法将通过索引结点跳到下一层,重复刚才的搜索,直到找到需要查找的元素为止。图1是一个具有2级索引的跳跃表。

图1:具有2级索引的跳跃表的基本结构

图1:具有2级索引的跳跃表的基本结构
  ConcurrentSkipListMap 采用一种基于HM有序集合链表的算法来作为基本的链表实现,并且对这种算法进行了改进,因此 ConcurrentSkipListMap 采用的无锁链表算法比HM有序集合链表更加高效并且节省存储空间。

HM有序集合链表

  HM有序集合链表是一种无锁的非阻塞式链表,其基本思想就是为了消除无锁链表删除结点时对其他线程并发访问链表的影响,从而引入了标记域,在删除结点时,先修改标记域为删除标记,然后再修改后继引用域,而标记域和引用域需要原子的进行修改,因此使用 java.util.concurrent.atomic.AtomicMarkableReference 将标记域和后继引用域封装在一起,实现对这两个变量的原子修改。所以HM有序集合链表算法的主要问题有两个:

  • AtomicMarkableReference 的使用和标记域的引入,会带来额外的存储空间消耗;
  • 对标记域和引用域的原子修改需要额外的性能损耗。
ConcurrentSkipListMap 的改进措施

  ConcurrentSkipListMap 对HM有序集合链表算法进行了改进,这些改进不但提高了性能,并且节省了存储空间

http://www.xdnf.cn/news/6602.html

相关文章:

  • 如何安全擦除 SSD 上的可用空间
  • Python包、模块、类的导入语法与机制解析
  • 解码生命语言:深度学习模型TranslationAI揭示RNA翻译新规则
  • 什么是模态内异质性,什么是模态间异质性?
  • zabbix7.2 zabbix-agent自动注册 被动模式(五)
  • SpringBoot基础(静态资源导入)
  • 观测云产品更新 | 安全监测、事件中心、仪表板AI智能分析等
  • 数据结构与算法--顺序表--单链表
  • python可视化:北方省市GDP与人口变化关系分析4
  • C++二项式定理:原理、实现与应用
  • Rust 数据结构:Vector
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.4.5)
  • FEKO许可证激活错误解决方法
  • 【Ansible基础】Ansible 核心组件深度解析:控制节点、受管节点、Inventory与Playbook
  • 建筑迈向绿色发展之路,楼宇自控成建筑可持续发展关键技术
  • 考研408《计算机组成原理》复习笔记,第二章(2)数值数据的表示和运算(浮点数篇)
  • 2025年大厂C++面试题总结与解析
  • 如何在Windows右键新建菜单中添加自定义项,将notepad添加到新建菜单
  • 黑马程序员C++2024版笔记 第0章 C++入门
  • Web安全科普:构建数字世界的“防盗门”
  • 贪吃蛇游戏消息通知功能开发全解析
  • 变分自编码器(Variational Autoencoder, VAE)
  • GDB的使用
  • TCSVT投稿记录
  • JAVA学习-练习试用Java实现“语音识别的基础 :如使用MFCC特征提取和简单的分类器”
  • Python 类变量与实例变量完全指南:区别、使用场景及常见陷阱
  • Vue 3中ref
  • 实验6 电子邮件
  • 【Java学习笔记】【第一阶段项目实践】零钱通(面向过程版本)
  • Vue3学习(组合式API——生命周期函数基础)