Java常用并发容器总结(四)
时间:2022-07-24
本文章向大家介绍Java常用并发容器总结(四),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
ConcurrentSkipListMap
1.介绍
跳表是一种可以用来快速查找的数据结构,类似于平衡树,他们都可以对元素进行快速的查找。但一个重要的区别是:对平衡树的插入往往可能导致平衡树进行一次全局的调整;而对跳表的插入和删除之需要的局部数据操作即可。这样的好处是,在高并发环境下,对平衡树的操作需要一个全局锁来保证线程安全,但是对于跳表则只需要部分锁,这样会拥有更好地性能。 就查询的性能而言,跳表的时间复杂度也是O(logN)。因此,在并发的数据结构中,JDK使用跳表实现一个Map。 跳表的本质是分层的多个链表,最上层的元素最少,查找操作从最上层开始进行。 使用跳表实现Map和使用Hash算法实现Map的另一个不同之处在于,HashMap并不会维护元素的顺序,而跳表内的所有元素都是排序的,在对跳表遍历时会得到一个有序的结果。因此,如果需要一个有序的并发安全的Map,使用跳表是不二的选择。
2.代码分析
ConcurrentSkipListMap是使用跳表实现的并发安全的Map结构,其内部由几个关键的数据结构组成。首先是Node。一个Node表示跳表的某一层的一个节点。
//一个Node表示跳表的一个节点
static final class Node<K,V> {
//该节点的key
final K key;
//该节点的value
volatile Object value;
//数据域,指向同一层的后继节点
volatile Node<K,V> next;
Node(K key, Object value, Node<K,V> next) {
this.key = key;
this.value = value;
this.next = next;
}
另一个重要的数据结构是Index,它内部包装了Node,同时增加了向下的引用和向右的引用:
static class Index<K,V> {
//内部封装了一个Node
final Node<K,V> node;
//数据域,指向下一层的节点
final Index<K,V> down;
//数据域,指向同一层的右边的节点
volatile Index<K,V> right;
Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
this.node = node;
this.down = down;
this.right = right;
}
此外,还有一个HeadIndex的数据结构,表示链表头部的第一个Index,并记录当前在第几层:
//HeadIndex表示第level层的表头Index
static final class HeadIndex<K,V> extends Index<K,V> {
//表示当前在第几层
final int level;
HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) {
super(node, down, right);
this.level = level;
}
}
对于跳表的所有操作,就是组织好这些Index之间的连接关系。
3.适用场景
如果想在高并发环境下,使用一个有序的Map,那么ConcurrentSkipListMap将是不二的选择。
- python爬取链家租房之获取房屋的链接和页面的详细信息
- 信用卡“坏账”客户分析(一)
- 一道简单的sql语句题
- python爬虫反爬取---设置User Agent自动变换header文件
- 一文读懂Python多线程
- 深入理解Python变量作用域与函数闭包
- TensorFlow从1到2 - 5 - 非专家莫入!TensorFlow实现CNN
- JetBrains Rider 破解 (ideaIU等等开发工具都通用)
- python中的小魔法(一)
- 由问题入手,步步爬出Python中赋值与拷贝的坑
- python爬取链家租房之获得每一页的房屋信息地址(持续更新)
- python使用正则表达式
- python在租房过程中的应用
- python爬虫反爬取---设置IP代理自动变换requests.get()中proxy的IP
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 别人变强靠天赋,而我,靠思维导图
- Spring Boot 五种热部署方式
- 二叉树最小深度
- 一日一技:限定Python函数只能被特定函数调用
- 四种ABAP单元测试隔离(test isolation)技术
- Python使用对象方式获取字典的值
- Hive整合HBase实现数据同步
- [数据结构与算法] 盘点工作中常用的算法
- MyBatis_resultMap 的关联方式实现多表查询(多对一)
- MyBatis_resultMap的N+1方式实现多表查询(多对 一)
- LeetCode 63. 不同路径 II
- 那些年遇到的刁钻JavaScript面试题(可防踩坑)
- JWT登录鉴权操作笔记 原
- c/c++补完计划(二-改): c字符串复制
- 来个鹅厂C语言面试题试试手?