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. STA之RC网

    STA的主要工作是计算电路网络的延时,如今的电路网络还是由CMOS cell和net组成的,所以STA所要计算的延时仍是电容的充放电时间.等量子计算机普及的时候,如今的这一套理论都将随着科技的进步被丢 ...

  2. Arctic Network(洛谷)--北极通讯网络(loj)

    洛谷传送门 loj传送门 一道蛮基础的最小生成树的题 题意也没绕什么圈子 只是叙述的有点累赘而已(loj上是这样的 也就读入加建边需要稍稍稍多想一下下 对于我这么一个蒟蒻 这是一道很好的板子题 (洛谷 ...

  3. 关于ActiveMq的Exception occurred while processing this request, check the log for more information!问题

    错误原因:jsp渲染的时候报错了.根本原因在于jdk版本和activemq版本的问题. 两种解决方案: 1.把jdk版本改为jdk1.7 2.activeMQ采用5.15,它依赖于jdk1.8

  4. ubuntu磁盘分配和挂载

    Linux(ubuntu)可以把分区作为挂载点,常用的几个挂载点.作用及一般应该分配的磁盘空间如下表所示: Markdown Extra 表格语法: 挂载点(目录) 建议大小 格式 作用 / 20G左 ...

  5. 好用的px转rem插件cssrem

    下载本项目,比如:git clone https://github.com/flashlizi/cssrem 进入packages目录:Sublime Text -> Preferences - ...

  6. mysql学习笔记(二:中的auto_increment 理解

    1.auto_increment 理解1 auto_increment是用于主键自动增长的,从1开始增长,当你把第一条记录删除时,再插入第二跳数据时,主键值是2,不是1. 例如: create tab ...

  7. MySQL死锁1

    MySQL行级排他锁的使用及死锁解除技巧 这篇笔记存粹是做学习记录之用,方便将来查阅,老鸟请跳过.关于MySQL排他锁的具体使用. 使用排他锁 假设有一张user表如下: id name age 1 ...

  8. centos610无桌面安装tomcat8

    1.下载安装包 wget https://www-us.apache.org/dist/tomcat/tomcat-8/v8.5.43/bin/apache-tomcat-8.5.43.tar.gz ...

  9. ASP.NET Core搭建多层网站架构【9.2-使用Castle.Core实现动态代理拦截器】

    2020/01/31, ASP.NET Core 3.1, VS2019, Autofac.Extras.DynamicProxy 4.5.0, Castle.Core.AsyncIntercepto ...

  10. 同步I/O和异步I/O

    同步I/O包括:阻塞,非阻塞,多路复用 阻塞模型:给你送的外卖到了,给你打电话,你不去取,外卖小哥一直在那等你,直到你来,形成阻塞,当然应该给外卖小哥点赞,哈哈哈哈!! 非阻塞模型:取外卖的主人非常饿 ...