并发集合(六)使用线程安全的NavigableMap
使用线程安全的NavigableMap
Java API 提供的有趣的数据结构,并且你可以在并发应用程序中使用,它就是ConcurrentNavigableMap接口的定义。实现ConcurrentNavigableMap接口的类存储以下两部分元素:
唯一标识元素的key 定义元素的剩余数据每部分在不同的类中实现。
Java API 也提供了这个接口的实现类,这个类是ConcurrentSkipListMap,它实现了非阻塞列表且拥有ConcurrentNavigableMap的行为。在内部实现中,它使用Skip List来存储数据。Skip List是基于并行列表的数据结构,它允许我们获取类似二叉树的效率。使用它,你可以得到一个排序的数据结构,这比排序数列使用更短的访问时间来插入、搜索和删除元素。
注意:在1990年,由William Pugh引入Skip List。
当你往map中插入数据时,它使用key来排序它们,所以,所有元素将是有序的。除了返回具体的元素,这个类也提供了获取map的子map的方法。
在这个指南中,你将学习如何使用ConcurrentSkipListMap类来实现一个通讯录的map。
准备工作…
这个指南的例子使用Eclipse IDE实现。如果你使用Eclipse或其他IDE,如NetBeans,打开它并创建一个新的Java项目。
如何做…
按以下步骤来实现的这个例子:
1.创建一个Contact类。
6.声明一个私有的、参数化为String类和Contact类的ConcurrentSkipListMap类型的属性map。
9.实现run()方法。使用任务的ID和创建Contact对象的增长数,在map中存储1000个不同的通讯录。使用put()方法添加通讯录到map中。
它是如何工作的...
在这个指南中,我们已实现Task类来存储Contact对象到NavigableMap 中。每个通讯录都有一个名称(创建它的任务的ID的)和电话号码(1000到2000之间的数字)。我们已使用这些值的连续值作为通讯录的key。每个Task对象创建1000个通讯录,并使用put()方法将它们存储到NavigableMap中。
注意:如果你插入的key已存在,那么这个key的元素将被新的元素取代。
Main类的main()方法创建25个Task对象,并使用A-Z的字母作为IDs。然后,你已使用一些方法从map中获取数据。firstEntry()方法返回map第一个元素的Map.Entry对象,且不会删除这个元素。这个对象包含key和元素。你已调用getValue()方法来获取元素。你可以使用getKey()来获取元素的key。
lastEntry()方法返回map最后一个元素的Map.Entry对象,subMap()方法返回map的部分元素的ConcurrentNavigableMap对象。在这个例子中,元素拥有A1996到B1002之间的key。在这种情况下,你可以使用pollFirst()方法来处理subMap()方法返回的这些元素。这个方法将返回并删除submap中的第一个Map.Entry对象。
以下截图显示了程序执行的输出:
不止这些...
ConcurrentSkipListMap类有其他有趣的方法,这些方法如下:
headMap(K toKey):K是参数化ConcurrentSkipListMap对象的Key值的类。返回此映射的部分视图,其键值小于 toKey。 tailMap(K fromKey):K是参数化ConcurrentSkipListMap对象的Key值的类。返回此映射的部分视图,其键大于等于 fromKey。 putIfAbsent(K key, V Value):如果key不存在map中,则这个方法插入指定的key和value。 pollLastEntry():这个方法返回并删除map中最后一个元素的Map.Entry对象。 replace(K key, V Value):如果这个key存在map中,则这个方法将指定key的value替换成新的value。参见
在第6章,并发集合中的使用非阻塞线程安全的数列指南高并发编程之线程间通信和集合的线程安全 3 线程间通信 线程间通信的模型有两种:共享内存和消息传递,以下方式都是基本这两种模 型来实现的。我们来基本一道面试常见的题目来分析 场景---两个线程,一个线程对当前数值加 1,另一个线程对当前数值减 1,要求用线程间通信 3.1 synchronized 方案 package com.atguigu.test; class DemoClass{ //加减对象 private int number = 0; * 加 1 public synchronized void increment() { try {
PS:最近是跳槽的高峰期,我连日加班好多天,整理出了包含16000 多道面试题的面试宝典,并且指北君也会持续更新这份面试宝典中的题目,希望它能帮助大家找到自己心仪的工作! 线程安全一直是多线程开发中需要注意的地方,可以说,并发安全保证了所有的数据都安全。
ConcurrentHashMap线程安全吗 ConcurrentHashMap 是 Java 并发包中提供的一个线程安全且高效的 HashMap 实现,以弥补 HashMap 不适合在并发环境中操作使用的不足。
C#线程安全使用(五) CancellationToken的多种应用 这是线程安全的最后一篇了,主要介绍CancellationToken的多种应用。 1,ThreadPool直接启动线程,传递CancellationToken。
线程安全性 要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的和可变的状态的访问。 共享 意味着变量可以由多个线程同时访问,而可变则意味着变量的值在其生命周期内可以发生变化。
ali清英 方腾飞,花名清英,英文名kiral,并发编程网创始人,支付宝技术专家,《Java并发编程的艺术》作者。
相关文章
- 并发集合(四)用优先级对使用阻塞线程安全的列表排序
- 并发编程2-安全的发布对象
- 系统捕获异常并发送到服务器
- Servlet, Struts2和SpringMVC 并发访问线程安全问题
- Redis自旋锁解决分布高并发问题:使线程异步变为同步执行
- 并发编程中,你加的锁未必安全
- Go并发
- 【成为架构师课程系列】怎样进行高性能高可用的高并发系统的设计?
- 【Android 内存优化】垃圾回收算法 ( 分代收集算法 | Serial 收集器 | ParNew 收集器 | Parallel Scavenge 收集器 | CMS 并发标记清除收集器 )
- 并发容器之CopyOnWriteArrayList
- Java并发编程:并发容器之CopyOnWriteArrayList
- Java并发编程与高并发之安全发布对象
- 【高并发】终于弄懂为什么局部变量是线程安全的了!!
- 【高并发】什么是ForkJoin?看这一篇就够了!
- Go语言自学系列 | golang并发编程之原子操作详解
- Java软件开发 | 高并发编程篇之——安全访问的集合(2)
- Java软件开发 | 高并发编程篇之——安全访问的集合(1)
- Swoole 协程的并发调用及使用示例
- C# 并发安全集合ConcurrentBag取代List
- 【并发编程】JUC并发编程(彻底搞懂JUC)
- Java开发之高并发编程篇(八)——安全访问的集合(1)