005-多线程-集合-Map-ConcurrentSkipListMap
一、概述
ConcurrentSkipListMap是线程安全的有序的哈希表,适用于高并发的场景。
ConcurrentSkipListMap和TreeMap,它们虽然都是有序的哈希表。但是,第一,它们的线程安全机制不同,TreeMap是非线程安全的,而ConcurrentSkipListMap是线程安全的。第二,ConcurrentSkipListMap是通过跳表实现的,而TreeMap是通过红黑树实现的。
关于跳表(Skip List),它是平衡树的一种替代的数据结构,但是和红黑树不相同的是,跳表对于树的平衡的实现是基于一种随机化的算法的,这样也就是说跳表的插入和删除的工作是比较简单的。
1.1、原理和数据结构
说明:
先以数据“7,14,21,32,37,71,85”序列为例,来对跳表进行简单说明。
跳表分为许多层(level),每一层都可以看作是数据的索引,这些索引的意义就是加快跳表查找数据速度。每一层的数据都是有序的,上一层数据是下一层数据的子集,并且第一层(level 1)包含了全部的数据;层次越高,跳跃性越大,包含的数据越少。
跳表包含一个表头,它查找数据时,是从上往下,从左往右进行查找。现在“需要找出值为32的节点”为例,来对比说明跳表和普遍的链表。
情况1:链表中查找“32”节点
路径如下图1-02所示:
需要4步(红色部分表示路径)。
情况2:跳表中查找“32”节点
路径如下图1-03所示:
忽略索引垂直线路上路径的情况下,只需要2步(红色部分表示路径)。
下面说说Java中ConcurrentSkipListMap的数据结构。
(01) ConcurrentSkipListMap继承于AbstractMap类,也就意味着它是一个哈希表。
(02) Index是ConcurrentSkipListMap的内部类,它与“跳表中的索引相对应”。HeadIndex继承于Index,ConcurrentSkipListMap中含有一个HeadIndex的对象head,head是“跳表的表头”。
(03) Index是跳表中的索引,它包含“右索引的指针(right)”,“下索引的指针(down)”和“哈希表节点node”。node是Node的对象,Node也是ConcurrentSkipListMap中的内部类。
1.2、示例
/*
* ConcurrentSkipListMap是“线程安全”的哈希表,而TreeMap是非线程安全的。
*
* 下面是“多个线程同时操作并且遍历map”的示例
* (01) 当map是ConcurrentSkipListMap对象时,程序能正常运行。
* (02) 当map是TreeMap对象时,程序会产生ConcurrentModificationException异常。
*/
public class ConcurrentSkipListMapDemo1 { // TODO: map是TreeMap对象时,程序会出错。
//private static Map<String, String> map = new TreeMap<String, String>();
private static Map<String, String> map = new ConcurrentSkipListMap<String, String>(); public static void main(String[] args) { // 同时启动两个线程对map进行操作!
new MyThread("a").start();
new MyThread("b").start();
} private static void printAll() {
String key, value;
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
key = (String) entry.getKey();
value = (String) entry.getValue();
System.out.print("(" + key + ", " + value + "), ");
}
System.out.println();
} private static class MyThread extends Thread {
MyThread(String name) {
super(name);
} @Override
public void run() {
int i = 0;
while (i++ < 6) {
// “线程名” + "序号"
String val = Thread.currentThread().getName() + i;
map.put(val, "0");
// 通过“Iterator”遍历map。
printAll();
}
}
}
}
1.3、使用场景
二、源码分析
005-多线程-集合-Map-ConcurrentSkipListMap的更多相关文章
- 【死磕 Java 集合】— ConcurrentSkipListMap源码分析
转自:http://cmsblogs.com/?p=4773 [隐藏目录] 前情提要 简介 存储结构 源码分析 主要内部类 构造方法 添加元素 添加元素举例 删除元素 删除元素举例 查找元素 查找元素 ...
- Java集合—Map
简介 Map用户保存具有映射关系的数据,因此Map集合里保存着两组数,一组值用户保存Map里的key,另一组值用户保存Map里的value,key和value都可以是任何引用类型的数据.Map的key ...
- 备战金三银四!一线互联网公司java岗面试题整理:Java基础+多线程+集合+JVM合集!
前言 回首来看2020年,真的是印象中过的最快的一年了,真的是时间过的飞快,还没反应过来年就夸完了,相信大家也已经开始上班了!俗话说新年新气象,马上就要到了一年之中最重要的金三银四,之前一直有粉丝要求 ...
- Java集合Map接口与Map.Entry学习
Java集合Map接口与Map.Entry学习 Map接口不是Collection接口的继承.Map接口用于维护键/值对(key/value pairs).该接口描述了从不重复的键到值的映射. (1) ...
- (10)集合之双列集合Map,HashMap,TreeMap
Map中的元素是两个对象,一个对象作为键,一个对象作为值.键不可以重复,但是值可以重复. 看顶层共性方法找子类特有对象. Map与Collection在集合框架中属并列存在 Map存储的是键值对 Ma ...
- 【由浅入深理解java集合】(五)——集合 Map
前面已经介绍完了Collection接口下的集合实现类,今天我们来介绍Map接口下的两个重要的集合实现类HashMap,TreeMap.关于Map的一些通用介绍,可以参考第一篇文章.由于Map与Lis ...
- (7)Java数据结构--集合map,set,list详解
MAP,SET,LIST,等JAVA中集合解析(了解) - clam_clam的专栏 - CSDN博---有颜色, http://blog.csdn.net/clam_clam/article/det ...
- 双列集合Map
1.双列集合Map,就是存储key-value的键值对. 2.hashMap中键必须唯一,值可以不唯一. 3.主要方法:put添加数据 getKey---通过key获取数据 keySet- ...
- 12:集合map、工具类
一.map集合 Map:一次添加一对元素.Collection 一次添加一个元素. Map也称为双列集合,Collection集合称为单列集合. 其实map集合中存储的就是键值对(结婚证书), map ...
- 20_java之集合Map
01Map集合概述 A:Map集合概述: 我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同 a:Collection中的集合,元素是孤立 ...
随机推荐
- Linux的desktop文件正常编写赋权,仍无法打开解决办法
Linux的desktop文件正常编写赋权,仍无法打开解决办法 如果你像我一样遇到了这个问题, 明明都没有问题, desktop文件不显示图标, 双击打开是文本编辑器, 同时也有执行权限 打开却是这样 ...
- grafana忘记登陆密码
找到grafana的数据文件grafana.db find / -name "grafana.db" ps:默认的安装路径为/var/lib/grafana/grafana.db ...
- centos7 修改内核文件 网卡名称为标准名称eth0
在开机安装系统之前按TAB键后输入标记信息后安装系统就可以变成标准网卡接口eth0 或eth1
- SpringBoot下,@WebFilter配置获取日志
CREATE TABLE [dbo].[SWEBSERVICELOG]( [WLG_ID] [varchar](100) NOT NULL, [WLG_SESSIONID] [varchar](100 ...
- java基础(2)---基本语法
一.程序注释 二.HelloWorld 三.关键字 四.常量 五.变量 六.标识符: 七.数据类型 数据类型间的转换: (1)自主转换:不需要明确指出所要转化的类型是什么,而是由java虚拟机自动转化 ...
- 【BZOJ3691】游行 最小可相交路径覆盖转化
因为C是不断变化的而且C是和点权相关和边权无关 所以我们可以MCMF但是MCMF的时候不能与C相关 再分析问题 我们可以认为每条路径S->T只覆盖T这个终点 因为题目中说了如果Si != Ti ...
- 包,logging日志模块,copy深浅拷贝
一 包 package 包就是一个包含了 __init__.py文件的文件夹 包是模块的一种表现形式,包即模块 首次导入包: 先创建一个执行文件的名称空间 1.创建包下面的__init__.py文件的 ...
- vscode源码编译疑难问题
最近把原来老的源码merge到了新的1.15版本源码,以前的依赖问题会导致各种错误,Loading "gc-signals" failed啦,Error: %1 is not a ...
- Windows10-Neo4j安装问题及解决方案
暑假都过得差不多了才终于开始搭环境了 1.下载Neo4j Neo4j官网下载翻墙的话还可以 不翻墙的话下了好几次都下不下来 不用下载desktop,下载community server就可以了 2.下 ...
- 定时器 延时调用setTimeout
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...