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中的集合,元素是孤立 ...
随机推荐
- 【转】用 Consul 来做服务注册与服务发现
原文:https://segmentfault.com/a/1190000018731395?utm_source=tag-newest ------------------------------- ...
- for,foreach,$.each()跳出循环的比较
说起跳出循环,第一时间想起的是 break \ continue,这是经典的for循环. 1.for 循环 先上例子,思考输出结果,体会 break 与 continue 的不同. 1 var arr ...
- jquerymobile tap事件被触发两次
首先介绍一下这个问题出现的背景:我在写网站时想要一套代码兼容手机端和pc端,所以用了jquery和jquery mobile,点击事件用的jquerymobile tap事件,但是在移动端测试时出现点 ...
- Python通过yagmail和smtplib模块发送简单邮件
SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件.HTML邮件以及带附件的邮件.python发邮件需要掌握两个模块的用法,smtplib和email,这俩模块是pytho ...
- ActionChains方法
click(on_element=None) ——单击鼠标左键 click_and_hold(on_element=None) ——点击鼠标左键,不松开 context_click(on_elemen ...
- 突然萌发关于 redis 的想法(2)
接着上篇的说.. 上一篇 : 突然萌发关于 Redis 的想法(1) 今天写商城的时候突然发现,其实商城这种 频繁操作,频繁更新, 等操作,都只需要全部存储在 Redis 中就行了, 可能有部分数据会 ...
- div 水平垂直居中
css <style> .main{ background: #999999; width: 600px; height: 400px; position: absolute; top: ...
- 原生JS实现购物车全选多选按钮功能
对于JS初学者来说,一个完整的购物车实现还是挺难的,逻辑功能挺多.写出完整功能,能提升不少JS基础,下面实现购物车全选多选按钮功能: 首先HTML及CSS部分: <style> table ...
- git查看commit提交记录详情
相关的命令: git log:查看所有的commit提交记录: git show: 查看提交的详情: 首先,需要通过git log打印所有commit记录,例如: 1.查看最新的commit:git ...
- Laravel 项目架构 弹性、可维护性
公司项目可能需要对架构进行重建,老大给了我一个视频让我学习里面的思想,看完后觉得收获很大,主讲人对laravel项目各个层次有很清晰的理解,力求做到职责单一分明,提高可维护性.下面是我看完视频对其内容 ...