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. P&R 5

    Floorplan: 要做好floorplan需要掌握哪些知识跟技能? 通常,遇到floorplan问题,大致的debug步骤跟方法有哪些? 如何衡量floorplan的QA? 芯片的整体架构模块划分 ...

  2. vue去掉地址栏# 方法

    超简单 export default new Router({ //将mode 设置为‘history‘ 即可.默认情况是’hash’ 所以会有丑陋的# mode: 'history', routes ...

  3. maven版axis2调用cxf服务端开发客户端(三)

    一.新建一个maven项目 二.pom.xml引入axis2依赖 <dependency> <groupId>org.apache.axis2</groupId> ...

  4. 算法刷题--回溯算法与N皇后

    所谓回溯算法,在笔者看来就是一种直接地思想----假设需要很多步操作才能求得最终的解,每一步操作又有很多种选择,那么我们就直接选择其中一种并依次深入下去.直到求得最终的结果,或是遇到明细的错误,回溯到 ...

  5. js中的日期控件My97 DatePicker

    使用WdatePicker插件来渲染日期类型的页面. 以下代码用到的属性有: isShowClear是否显示清空按钮 skin皮肤的样式 readOnly是否只读 maxDate:最大的选择时间 &l ...

  6. STM32CUBEMX使用操作记录

    1.New Project 2.选择芯片型号 3.配置相关外设 4.例如选择了GPIO_Output 5.配置时钟树 灰色框点不了,这和你上一步相关外设配置有关,鼠标靠近灰色框,系统会给出提示 6.工 ...

  7. PTA的Python练习题(十六)

    第4章-15 换硬币 挺难的,这里学到一个range的用法: 也就是说range函数能实现顺序和倒序,取决于step是正是负 count = 0 x = int(input()) a = x // 5 ...

  8. 吴裕雄 python 机器学习——模型选择回归问题性能度量

    from sklearn.metrics import mean_absolute_error,mean_squared_error #模型选择回归问题性能度量mean_absolute_error模 ...

  9. 理解Spring 容器、BeanFactory 以及 ApplicationContext

    一.spring 容器理解 spring 容器可以理解为生产对象(Object)的地方,在这里容器不只是帮助我们创建对象那么简单,它负责了对象的整个生命周期-创建.装配.销毁.而这里对象的创建管理的控 ...

  10. drat笔记

    安装dart https://www.dartcn.com/install http://www.cndartlang.com/920.html 所有执行的方法都在main里面. main() {} ...