一、前言:

JDK为我们提供了很多Map接口的实现,使得我们可以方便地处理Key-Value的数据结构。

当我们希望快速存取<Key, Value>键值对时我们可以使用HashMap。

当我们希望在多线程并发存取<Key, Value>键值对时,我们会选择ConcurrentHashMap。

TreeMap则会帮助我们保证数据是按照Key的自然顺序或者compareTo方法指定的排序规则进行排序。

OK,那么当我们需要多线程并发存取<Key, Value>数据并且希望保证数据有序时,我们需要怎么做呢?

。。。。。。

也许,我们可以选择ConcurrentTreeMap。不好意思,JDK没有提供这么好的数据结构给我们。

当然,我们可以自己添加lock来实现ConcurrentTreeMap,但是随着并发量的提升,lock带来的性能开销也随之增大。

Don't cry......,JDK6里面引入的ConcurrentSkipListMap也许可以满足我们的需求。

JDK Documentation对ConcurrentSkipListMap的介绍

通过上面的介绍我们可以对ConcurrentSkipListMap中基本操作的时间复杂度有个基本的了解:

Operation Time Complexity
Insertion O(log N)
Removal O(log N)
Check if contains O(log N)
Enumerate in order O(N)

二、ConcurrentSkipListMap实例:

 import java.util.Iterator;
import java.util.NavigableSet;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap; public class ConcurrentSkipListMapExample {
public static void main(String[] args) {
ConcurrentNavigableMap<String, String> concurrentSkipListMap = new ConcurrentSkipListMap<String, String>();
concurrentSkipListMap.put("3", "Wednesday");
concurrentSkipListMap.put("2", "Tuesday");
concurrentSkipListMap.put("1", "Monday");
concurrentSkipListMap.put("5", "Friday");
concurrentSkipListMap.put("4", "Thursday"); NavigableSet<String> navigableSet = concurrentSkipListMap.descendingKeySet();
System.out.println("descendingKeySet: ");
Iterator<String> itr = navigableSet.iterator();
while (itr.hasNext()) {
String s = itr.next();
System.out.println(s);
}
System.out.println("ceilingEntry-2: " + concurrentSkipListMap.ceilingEntry("2"));
System.out.println("firstEntry: " + concurrentSkipListMap.firstEntry());
System.out.println("lastEntry: " + concurrentSkipListMap.lastEntry());
System.out.println("pollFirstEntry: " + concurrentSkipListMap.pollFirstEntry());
System.out.println("now firstEntry: " + concurrentSkipListMap.firstEntry());
System.out.println("pollLastEntry: " + concurrentSkipListMap.pollLastEntry());
System.out.println("now lastEntry: " + concurrentSkipListMap.lastEntry());
System.out.println("Entry-2: " + concurrentSkipListMap.get("2"));
} }

三、ConcurrentSkipListMap性能测试:

下面,我们来比较一下ConcurrentSkipListMap与TreeMap在并发情况下查询的性能状况。

我们会启动n个线程随机读取Map中的记录,每个线程会读取106次。

从测试结果,我们可以看出随着并发度的不断提高,ConcurrentSkipListMap相对于TreeMap的优势也越来越明显。

四、ConcurrentSkipListMap实现原理

skiplist数据结构介绍:

http://kenby.iteye.com/blog/1187303

concurrentskiplistmap实现并发的原理:

concurrentskiplistmap并没有使用lock来保证线程的并发访问和修改,而是使用了非阻塞算法来保证并发访问(Michael-Scott 算法)

也可以参考下面的博客(http://blog.csdn.net/jy3161286/article/details/22809913)

ConcrrentSkipListMap介绍和原理分析的更多相关文章

  1. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  2. AbstractQueuedSynchronizer的介绍和原理分析(转)

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  3. Servlet过滤器介绍之原理分析

    zhangjunhd 的BLOG     写留言去学院学习发消息 加友情链接进家园 加好友 博客统计信息 51CTO博客之星 用户名:zhangjunhd 文章数:110 评论数:858 访问量:19 ...

  4. Hadoop数据管理介绍及原理分析

    Hadoop数据管理介绍及原理分析 最近2014大数据会议正如火如荼的进行着,Hadoop之父Doug Cutting也被邀参加,我有幸听了他的演讲并获得亲笔签名书一本,发现他竟然是左手写字,当然这个 ...

  5. AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  6. 转:AbstractQueuedSynchronizer的介绍和原理分析

    引自:http://ifeve.com/introduce-abstractqueuedsynchronizer/ 简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同 ...

  7. TKmybatis的框架介绍和原理分析及Mybatis新特性

    tkmybatis是在mybatis框架的基础上提供了很多工具,让开发更加高效,下面来看看这个框架的基本使用,后面会对相关源码进行分析,感兴趣的同学可以看一下,挺不错的一个工具 实现对员工表的增删改查 ...

  8. TKmybatis的框架介绍和原理分析及Mybatis新特性演示

    tkmybatis是在mybatis框架的基础上提供了很多工具,让开发更加高效,下面来看看这个框架的基本使用,后面会对相关源码进行分析,感兴趣的同学可以看一下,挺不错的一个工具 实现对员工表的增删改查 ...

  9. logistic回归介绍以及原理分析

    1.什么是logistic回归? logistic回归虽然说是回归,但确是为了解决分类问题,是二分类任务的首选方法,简单来说,输出结果不是0就是1 举个简单的例子: 癌症检测:这种算法输入病理图片并且 ...

随机推荐

  1. Find non-overlap jobs with max cost

    Given a set of n jobs with [start time, end time, cost] find a subset so that no 2 jobs overlap and ...

  2. Ubuntu修改中文目录为英文

    1.安装需要的软件 sudo apt install xdg-user-dirs-gtk 2.临时转换系统语言为英文,重启后会自动恢复原值的 export LANG=en_US 3.执行转换命令,弹出 ...

  3. DAY5-Flask项目

    1.验证参数(WTForms): 当URL为/book/search?q= &page=1 时 ,p=空格,验证器会通过,在forms验证层的book.py文件中添加DataRequired验 ...

  4. python使用selenium、PhantomJS获得网站cookie信息#windows

    首先python安装selenium,命令行中输入 pip install selenium 在执行代码如下代码时出现错误 driver=webdriver.PhantomJS() 错误如下 sele ...

  5. eclipse 重装了tomcat后配置路径

    在Windows->Preferences->Server->Runtime Environments把先前的工程Servers删除掉

  6. C++ 构造函数初始化列表

    C++ 中类初始化列表执行顺序是按照定义的顺序执行,不是写在初始化列表的顺序执行 #include <bits/stdc++.h> using namespace std; class N ...

  7. 51nod 1471 小S的兴趣 | 分块 链表

    51nod 1471 小S的兴趣 题面 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题 ...

  8. 正确理解 LEAL (Load Effective Address) 指令

    LEAL: leal S, D    ->    D ← &S 在 CSAPP (Computer Systems: A Programmer’s Perspective) 中,对 LE ...

  9. phpmyadmin 配置方法

    几乎所有的配置参数都在 config.inc.php 文件中.如果这个文件不存在,您可以在 libraries 目录中找到 config.default.php,将它复制到根目录,并改名为 confi ...

  10. CentOS 7.0源码包搭建LNMP方法分享(实际环境下)

    CentOS 7.0编译安装Nginx1.6.0+MySQL5.6.19+PHP5.5.14 一.配置防火墙,开启80端口.3306端口 CentOS 7.0默认使用的是firewall作为防火墙,这 ...