并发容器小结及ConcurrentSkipListMap介绍——并发系列(十一)

目录

概述

ConcurrentHashMap

CopyOnWriteArrayList

ConcurrentLinkedQueue

BlockingQueue

ConcurrentSkipListMap

设计目的

功能特性

与其他相关类对比

适用场景


概述

JDK提供的这些容器大部分在 java.util.concurrent 包中。我们这里挑选出了一些比较有代表性的并发容器类,来感受一下JDK自带的并发集合带来的便利:

        在前面几篇也分别对这些类进行了使用场景介绍及源码解析:

ConcurrentHashMap

ConcurrentHashMap源码解析

CopyOnWriteArrayList

CopyOnWriteArrayList源码解析

ConcurrentLinkedQueue

ConcurrentLinkedQueue源码解析

BlockingQueue

阻塞队列BlockingQueue应用及源码解析

ConcurrentSkipListMap

        它实现了 ConcurrentMap 接口,提供了线程安全的有序映射

设计目的

  ConcurrentSkipListMap 的设计目的是在多线程环境下提供一个有序的、线程安全的键值对映射结构。它通过跳表(Skip List)数据结构来实现高效的查找、插入和删除操作,同时保证在多线程并发访问时的数据一致性和线程安全性。与基于红黑树实现的 TreeMap 不同,跳表结构在并发环境下具有更好的扩展性和性能。

功能特性

有序性ConcurrentSkipListMap 按照键的自然顺序(如果键实现了 Comparable 接口)或在构造时提供的 Comparator 进行排序。这使得可以方便地对映射中的键值对进行范围查询、遍历等操作。例如:

ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
map.put(3, "three");
map.put(1, "one");
map.put(2, "two");
System.out.println(map.firstKey()); // 输出 1
System.out.println(map.lastKey());  // 输出 3

线程安全性ConcurrentSkipListMap 是线程安全的,可以在多线程环境下安全地进行读写操作。多个线程可以同时读取映射,而写入操作(如插入、删除、更新)也能在不影响其他线程读取的情况下进行,通过内部的锁分段技术和无锁数据结构实现高效并发控制。

ExecutorService executorService = Executors.newFixedThreadPool(10);
ConcurrentSkipListMap<Integer, String> concurrentMap = new ConcurrentSkipListMap<>();
for (int i = 0; i < 10; i++) {
    executorService.submit(() -> {
        concurrentMap.put((int) (Math.random() * 100), "value");
    });
}
executorService.shutdown();

高效的操作性能:跳表结构使得 ConcurrentSkipListMap 在查找、插入和删除操作上具有平均 O(logn) 的时间复杂度,其中 n 是映射中的元素数量。这使得它在处理大量数据时,性能表现良好。尤其在高并发读多写少的场景下,性能优势更为明显。

范围查询:支持范围查询操作,例如可以获取键在某个范围内的子映射。例如:

ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
// 填充数据
map.put(1, "a");
map.put(3, "c");
map.put(5, "e");
ConcurrentNavigableMap<Integer, String> subMap = map.subMap(2, true, 4, true);
System.out.println(subMap); // 输出 {3=c}

与其他相关类对比

  • 与 TreeMap 对比
    • 线程安全性TreeMap 不是线程安全的,在多线程环境下需要外部同步机制来保证线程安全;而 ConcurrentSkipListMap 本身就是线程安全的,适合多线程并发访问。
    • 性能:在高并发场景下,ConcurrentSkipListMap 由于采用跳表结构和更细粒度的并发控制,通常比使用外部同步的 TreeMap 性能更好。
  • 与 ConcurrentHashMap 对比
    • 有序性ConcurrentHashMap 不保证键的顺序,而 ConcurrentSkipListMap 保证键的有序性。如果应用需要按照键的顺序进行操作,如范围查询、遍历等,ConcurrentSkipListMap 是更好的选择。
    • 性能ConcurrentHashMap 在高并发读写场景下具有非常高的性能,尤其是在写操作较多的情况下。而 ConcurrentSkipListMap 在范围查询和有序遍历方面表现更好,读操作性能也不错,但写操作相对 ConcurrentHashMap 可能稍慢,因为需要维护跳表结构的有序性。

适用场景

  • 缓存系统:当缓存需要按照某种顺序(如访问时间、过期时间等)进行管理时,ConcurrentSkipListMap 可以作为缓存的底层数据结构。例如,实现一个带有过期策略的缓存,按照过期时间排序,便于清理过期数据。
  • 实时统计:在实时统计系统中,需要对数据按照某个维度(如时间戳、数值大小等)进行排序并实时更新。例如,统计一段时间内用户的登录次数,并按照登录次数排序展示,ConcurrentSkipListMap 可以满足这种需求。
  • 索引结构:在一些需要对数据建立索引,并支持多线程并发访问和范围查询的场景下,ConcurrentSkipListMap 可以作为索引的实现方式。例如,在数据库的某些索引模块中,使用 ConcurrentSkipListMap 可以提供高效的并发访问和范围查找功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值