Java中如何通过ConcurrentSkipListMap实现有序并发Map

来源:苹果APP网作者:北京SEO公司头衔:草根站长
导读:本期聚焦于小伙伴创作的《Java中如何通过ConcurrentSkipListMap实现有序并发Map》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java中如何通过ConcurrentSkipListMap实现有序并发Map》有用,将其分享出去将是对创作者最好的鼓励。

在Java的并发集合体系中,ConcurrentSkipListMap是少数支持线程安全且元素有序的Map实现,它不需要额外的同步措施就能在多线程环境下安全使用,同时默认按照键的自然顺序或者构造时传入的比较器排序,非常适合需要并发访问且要求元素有序的场景。

ConcurrentSkipListMap核心特性

ConcurrentSkipListMap的内部基于跳表(Skip List)数据结构实现,跳表是一种可以替代平衡树的有序数据结构,插入、删除、查询的时间复杂度都是O(log n),同时实现难度比平衡树更低,并发控制上也更容易扩展。

它的核心特性主要有以下几点:

  • 线程安全:所有操作都不需要外部同步,支持多线程并发读写,不会抛出ConcurrentModificationException。
  • 有序性:默认按照键的自然顺序排序,也可以在构造时传入自定义的Comparator实现指定排序规则。
  • 弱一致性:迭代器是弱一致性的,不会抛出并发修改异常,但是可能不会反映迭代过程中其他线程的修改。
  • 支持导航操作:提供了很多类似排序相关的导航方法,比如获取第一个键、最后一个键、小于等于某个键的最大键等。

基本使用方式

构造方法说明

ConcurrentSkipListMap提供了多种构造方法,开发者可以根据需要选择:

import java.util.Comparator;
import java.util.concurrent.ConcurrentSkipListMap;

public class SkipListMapDemo {
    public static void main(String[] args) {
        // 1. 无参构造,按照键的自然顺序排序,要求键实现Comparable接口
        ConcurrentSkipListMap<Integer, String> naturalOrderMap = new ConcurrentSkipListMap<>();
        
        // 2. 传入自定义Comparator,按照指定规则排序
        // 这里实现倒序排序,键越大越靠前
        ConcurrentSkipListMap<Integer, String> customOrderMap = new ConcurrentSkipListMap<>(
            new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o2.compareTo(o1);
                }
            }
        );
        
        // 3. 传入已有的Map初始化,会按照自然顺序或者比较器排序原有元素
        // ConcurrentSkipListMap<Integer, String> initMap = new ConcurrentSkipListMap<>(otherMap);
    }
}

常用基础操作

ConcurrentSkipListMap的基础操作和普通Map类似,但是额外提供了很多有序相关的导航方法:

import java.util.concurrent.ConcurrentSkipListMap;

public class BasicOperationDemo {
    public static void main(String[] args) {
        ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
        
        // 添加元素
        map.put(3, "value3");
        map.put(1, "value1");
        map.put(2, "value2");
        
        // 获取元素
        String val = map.get(1); // 返回value1
        
        // 删除元素
        map.remove(2);
        
        // 判断包含
        boolean hasKey = map.containsKey(3); // 返回true
        
        // 获取第一个键和最后一个键
        Integer firstKey = map.firstKey(); // 返回1
        Integer lastKey = map.lastKey(); // 返回3
        
        // 获取小于等于指定键的最大键
        Integer floorKey = map.floorKey(3); // 返回3
        // 获取大于等于指定键的最小键
        Integer ceilingKey = map.ceilingKey(2); // 返回3
        
        // 遍历元素,按照键的顺序输出
        map.forEach((k, v) -> System.out.println(k + ":" + v));
    }
}

并发场景下的使用示例

在多线程并发写入的场景下,ConcurrentSkipListMap不需要额外的同步措施就能保证线程安全,下面的例子模拟多个线程同时向Map中写入数据,最终遍历结果依然是有序的:

import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ConcurrentDemo {
    public static void main(String[] args) throws InterruptedException {
        ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        // 三个线程同时写入数据
        for (int i = 0; i < 3; i++) {
            int threadId = i;
            executor.submit(() -> {
                for (int j = 0; j < 5; j++) {
                    int key = threadId * 5 + j;
                    map.put(key, "thread" + threadId + "_value" + j);
                }
            });
        }
        
        // 等待所有线程执行完成
        executor.shutdown();
        while (!executor.isTerminated()) {
            Thread.sleep(100);
        }
        
        // 遍历结果,会按照key的自然顺序输出
        System.out.println("遍历结果:");
        map.forEach((k, v) -> System.out.println(k + ":" + v));
    }
}

和其他并发Map的对比

Java中常用的并发Map还有ConcurrentHashMap,两者的核心差异如下:

对比项ConcurrentSkipListMapConcurrentHashMap
有序性支持,默认自然顺序或者自定义比较器不支持,遍历顺序不确定
数据结构跳表数组+链表+红黑树
时间复杂度插入、删除、查询O(log n)插入、删除、查询O(1)(理想情况)
适用场景需要有序且并发访问的场景不需要排序的高并发读写场景

注意事项

  • 键必须支持排序:如果使用无参构造,键必须实现Comparable接口,否则会抛出ClassCastException。
  • 自定义比较器要一致:如果传入自定义Comparator,要保证比较规则和equals方法逻辑一致,避免出现逻辑错误。
  • 弱一致性迭代器:迭代过程中如果其他线程修改了Map,迭代器可能不会反映这些修改,需要根据业务场景判断是否可以接受。
  • 不支持null键和null值:和大多数并发集合一样,ConcurrentSkipListMap不允许插入null键或者null值,否则会抛出NullPointerException。
总结来说,当需要在Java中实现有序的并发Map时,优先选择ConcurrentSkipListMap,它既满足了线程安全的要求,又能保证元素的有序性,使用方式也和普通的Map基本一致,学习成本很低。

ConcurrentSkipListMap有序并发MapJava并发集合跳表线程安全Map修改时间:2026-06-23 23:33:44

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。