java并发初探ConcurrentSkipListMap

ConcurrentSkipListMap以调表这种数据结构以空间换时间获得效率,通过volatile和CAS操作保证线程安全,而且它保证了有序性,比TreeMap比线程安全。

跳表结构

通过level down right可以更快插入和查找元素

     *
* Head nodes Index nodes
* +-+ right +-+ +-+
* |2|---------------->| |--------------------->| |->null
* +-+ +-+ +-+
* | down | |
* v v v
* +-+ +-+ +-+ +-+ +-+ +-+
* |1|----------->| |->| |------>| |----------->| |------>| |->null
* +-+ +-+ +-+ +-+ +-+ +-+
* v | | | | |
* Nodes next v v v v v
* +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
* | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null
* +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+

例子


package com.java.javabase.thread.collection; import lombok.extern.slf4j.Slf4j; import java.security.SecureRandom;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap; /**
* @author
*/
@Slf4j
public class ConcurrentSkipMapTest {
//public static TreeMap<String, Integer> map = new TreeMap();
public static ConcurrentSkipListMap<String, Integer> map = new ConcurrentSkipListMap<>();
public static int size = 10; public static void main(String[] args) {
InnerThread t1 =new InnerThread("t1");
InnerThread t2 =new InnerThread("t2");
t1.start();
t2.start();
try {
Thread.sleep(1000);
printMap(map);
} catch (InterruptedException e) {
e.printStackTrace();
} } static class InnerThread extends Thread {
String name;
public InnerThread(String name) {
super(name);
this.name=name;
} @Override
public void run() {
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < size; i++) {
String key =String.valueOf(random.nextInt(1000))+name;
//Wlog.info(key);
map.put(key, Integer.valueOf(i));
printMapNone(map);
} } } public static void printMap(Map<String, Integer> map) {
//Iterator<Map.Entry<K,V>> i = entrySet().iterator();
Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Integer> entry = it.next();
String key = entry.getKey();
Integer value = entry.getValue();
log.info("key {} value {}", key, value);
} } public static void printMapNone(Map<String, Integer> map) {
//Iterator<Map.Entry<K,V>> i = entrySet().iterator();
Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Integer> entry = it.next();
String key = entry.getKey();
Integer value = entry.getValue();
} }
}

run result

019-08-28 19:34:31,919   [main] INFO  ConcurrentSkipMapTest  - key 101t1 value 5
2019-08-28 19:34:31,921 [main] INFO ConcurrentSkipMapTest - key 101t2 value 5
2019-08-28 19:34:31,921 [main] INFO ConcurrentSkipMapTest - key 131t1 value 7
2019-08-28 19:34:31,921 [main] INFO ConcurrentSkipMapTest - key 131t2 value 7
2019-08-28 19:34:31,922 [main] INFO ConcurrentSkipMapTest - key 180t1 value 3
2019-08-28 19:34:31,922 [main] INFO ConcurrentSkipMapTest - key 180t2 value 3
2019-08-28 19:34:31,922 [main] INFO ConcurrentSkipMapTest - key 209t1 value 9
2019-08-28 19:34:31,922 [main] INFO ConcurrentSkipMapTest - key 209t2 value 9
2019-08-28 19:34:31,922 [main] INFO ConcurrentSkipMapTest - key 349t1 value 6
2019-08-28 19:34:31,922 [main] INFO ConcurrentSkipMapTest - key 349t2 value 6
2019-08-28 19:34:31,923 [main] INFO ConcurrentSkipMapTest - key 527t1 value 4
2019-08-28 19:34:31,923 [main] INFO ConcurrentSkipMapTest - key 527t2 value 4
2019-08-28 19:34:31,923 [main] INFO ConcurrentSkipMapTest - key 655t1 value 1
2019-08-28 19:34:31,923 [main] INFO ConcurrentSkipMapTest - key 655t2 value 1
2019-08-28 19:34:31,923 [main] INFO ConcurrentSkipMapTest - key 714t1 value 8
2019-08-28 19:34:31,923 [main] INFO ConcurrentSkipMapTest - key 714t2 value 8
2019-08-28 19:34:31,923 [main] INFO ConcurrentSkipMapTest - key 781t1 value 2
2019-08-28 19:34:31,924 [main] INFO ConcurrentSkipMapTest - key 781t2 value 2
2019-08-28 19:34:31,924 [main] INFO ConcurrentSkipMapTest - key 797t1 value 0
2019-08-28 19:34:31,924 [main] INFO ConcurrentSkipMapTest - key 797t2 value 0

java并发初探ConcurrentSkipListMap的更多相关文章

  1. java并发初探ConcurrentHashMap

    java并发初探ConcurrentHashMap Doug Lea在java并发上创造了不可磨灭的功劳,ConcurrentHashMap体现这位大师的非凡能力. 1.8中ConcurrentHas ...

  2. java并发初探ThreadPoolExecutor拒绝策略

    java并发初探ThreadPoolExecutor拒绝策略 ThreadPoolExecuter构造器 corePoolSize是核心线程池,就是常驻线程池数量: maximumPoolSize是最 ...

  3. java并发初探CyclicBarrier

    java并发初探CyclicBarrier CyclicBarrier的作用 CyclicBarrier,"循环屏障"的作用就是一系列的线程等待直至达到屏障的"瓶颈点&q ...

  4. java并发初探CountDownLatch

    java并发初探CountDownLatch CountDownLatch是同步工具类能够允许一个或者多个线程等待直到其他线程完成操作. 当前前程A调用CountDownLatch的await方法进入 ...

  5. java并发初探ReentrantWriteReadLock

    java并发初探ReentrantWriteReadLock ReenWriteReadLock类的优秀博客 ReentrantReadWriteLock读写锁详解 Java多线程系列--" ...

  6. Java并发指南14:Java并发容器ConcurrentSkipListMap与CopyOnWriteArrayList

    原文出处http://cmsblogs.com/ 『chenssy』 到目前为止,我们在Java世界里看到了两种实现key-value的数据结构:Hash.TreeMap,这两种数据结构各自都有着优缺 ...

  7. Java并发容器——ConcurrentSkipListMap和ConcurrentHashMap

    一:ConcurrentSkipListMap TreeMap使用红黑树按照key的顺序(自然顺序.自定义顺序)来使得键值对有序存储,但是只能在单线程下安全使用:多线程下想要使键值对按照key的顺序来 ...

  8. java并发:初探sleep方法

    sleep与wait sleep是Thread方法,使得当前线程从运行态变为阻塞态.但它不会释放对象的锁. wait方法是Object方法,它的作用是使得当前拥有对象锁的线程从运行态变为阻塞态, 它会 ...

  9. java并发队列

    阻塞队列 常见的阻塞队列有ArrayBlockingQueue,LinkedBlockingDeque,LinkedBlockingQueue,这些队列有界且可以阻塞线程 ArrayBlockingQ ...

随机推荐

  1. win api 音频可视化

    暂时记录,改天有时间再完善...其实写好好久了,但以前的代码丢了,重新写一遍.. 原理和 python 的一样,获取输入设备,然后把数据读取到 buffer 中,在绘制出来. 这里要注意两点: 1. ...

  2. LinuxC下argv,argc[]的意义

    MarkdownPad Document *:first-child { margin-top: 0 !important; } body>*:last-child { margin-botto ...

  3. SpringBoot踩坑记(HTTP 400 错误)

    HTTP 400 错误 复现错误 ajax请求后台数据时有时会报 HTTP 400 错误 - 请求无效 (Bad request);出现这个请求无效报错说明请求没有进入到后台服务里:原因:1)前端提交 ...

  4. 01-Spring的概述

    Spring概述 ①Spring是一个开源框架 ②Spring为简化企业级开发而生,使用Spring开发可以将Bean对象,Dao组件对象,Service组件对象等交给Spring容器来管理,这样使得 ...

  5. windows 10安装linux(ubuntu)子系统

    windows10安装ubuntu子系统系统 之前一直在虚拟机中使用linux系统,但是不是很方便,后来发现windows下也有了linux系统.感觉还不错 1. 打开windows应用市场micro ...

  6. 机器学习 — 从mnist数据集谈起

    做了一些简单机器学习任务后,发现必须要对数据集有足够的了解才能动手做一些事,这是无法避免的,否则可能连在干嘛都不知道,而一些官方例程并不会对数据集做过多解释,你甚至连它长什么样都不知道... 以skl ...

  7. Vue.nextTick DOM 更新循环结束之后执行延迟回调

    在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 DOM. 简单来说,Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统 ...

  8. Centos7 将应用添加快捷方式到applications 中以pycham为例[ubuntu]适用

    安装版本pycharm-2019.1.3 安装路径:/opt/pycharm-2019.1.3/ vim /usr/share/applications/pycharm.desktop #!/usr/ ...

  9. spring boot properties文件与yaml文件的区别

    编写是没有提示的话在pom中添加依赖,如下: <!-- 配置文件处理器 编写配置时会有提示 --> <dependency> <groupId>org.spring ...

  10. 进程作业管理2-kill,前后台作业,并行执行

    kill命令:向进程发送控制信号,以实现对进程管理,每个信号对应一个数字,信号名称以SIG开 头(可省略),不区分大小写 显示当前系统可用信号: kill –l   或者  trap -l 常用信号: ...