java并发体系----并发集合---ConcurrentSkipListMap&ConcurrentSkipListSet

发布时间:2024年01月03日

ConcurrentSkipListMap

ConcurrentSkipListMap是什么?

? ? ? ConcurrentSkipListMap是Java中的一个并发数据结构,它是基于跳表(skip list)的实现。它的特点是可以在多线程环境下高效地进行插入、删除和查找操作。

跳表是一种随机化的数据结构,类似于有序链表,但在链表的基础上通过添加多级索引来提高查找的效率。每一级索引中的节点以一定的概率选择原链表中的节点作为索引节点,从而使得在进行查找时可以跨越多个节点,从而加快查找速度。

ConcurrentSkipListMap是线程安全的

它使用了锁分段技术(lock striping)来实现并发访问。这意味着它通过将整个数据集分段并对每个段加锁,从而允许多个线程同时进行操作,提高了并发性能。

ConcurrentSkipListMap提供了许多与传统的TreeMap类似的方法,包括插入(put)、删除(remove)和查找(get)等。此外,它还提供了一些额外的方法,如获取指定范围内的元素(subMap)和获取最小/最大键(firstKey / lastKey)等。

需要注意的是,由于ConcurrentSkipListMap是有序的,插入、删除和查找操作的时间复杂度为O(log n),其中n是元素的数量。这使得它在需要高效并发访问的场景下特别有用,例如并发缓存、事件驱动编程等。

ConcurrentSkipListMap使用实例

? ? ConcurrentSkipListMap的使用示例代码如下:

import java.util.concurrent.ConcurrentSkipListMap;

public class Main {
    public static void main(String[] args) {
        // 创建ConcurrentSkipListMap对象
        ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();

        // 添加键值对
        map.put(1, "Apple");
        map.put(2, "Banana");
        map.put(3, "Orange");

        // 获取键对应的值
        String value = map.get(2); // 返回"Banana"
        System.out.println(value);

        // 删除键值对
        String removedValue = map.remove(1); // 返回"Apple"
        System.out.println(removedValue);

        // 遍历键值对
        for (Integer key : map.keySet()) {
            String val = map.get(key);
            System.out.println(key + " -> " + val);
        }
    }
}

上述代码中,首先创建了一个ConcurrentSkipListMap对象map。然后使用put方法向map中添加键值对。键为整数类型,值为字符串类型。

使用get方法可以根据键获取对应的值,这里通过获取键2的值,返回的结果为"Banana"。

使用remove方法可以删除指定键对应的键值对,这里删除了键1对应的键值对,返回的结果为"Apple"。

使用keySet方法可以获取ConcurrentSkipListMap中所有的键,并通过遍历获取对应的值进行打印。

ConcurrentSkipListMap的底层实现是基于跳表(SkipList),它能够在多线程环境下保持高效的并发访问性能。它是线程安全的,并且提供了按照键的自然顺序进行有序访问的能力。在多线程环境下使用ConcurrentSkipListMap时,可以安全地添加、删除和查找键值对,而不需要额外的同步措施。

ConcurrentSkipListSet

ConcurrentSkipListSet是什么

ConcurrentSkipListSet是Java中的一种线程安全的有序集合,它实现了Set接口,并且元素是按照升序排序的。

ConcurrentSkipListSet使用了跳表(skip list)的数据结构来实现。跳表是一种插入、删除、查找操作都具有O(log n)的时间复杂度的数据结构,相对于普通的有序集合例如TreeSet,它的插入和删除操作的效率更高。

ConcurrentSkipListSet允许多个线程同时对集合进行并发操作,不会出现线程安全问题。它的底层实现使用了CAS(Compare and Swap)原子操作和锁分段技术来保证线程安全。

由于ConcurrentSkipListSet是有序集合,所以它提供了一些额外的方法,例如first()返回最小的元素,last()返回最大的元素,subSet()返回指定范围内的子集合等。

需要注意的是,ConcurrentSkipListSet是不允许存储null元素的。如果尝试存储null元素,会抛出NullPointerException异常。

ConcurrentSkipListSet是线程安全的

ConcurrentSkipListSet 是线程安全的数据结构,具有以下原因:

  1. 内部使用跳表(Skip List)作为数据结构,跳表是一种有序的链表结构,它通过层级索引的方式提高了查询效率。多线程并发的访问和修改操作可以通过跳表的层级结构而不会产生竞争条件,从而保证线程安全。

  2. ConcurrentSkipListSet 内部使用 CAS(Compare And Swap)操作来实现并发控制。CAS 是一种无锁算法,它可以保证多线程并发访问时的原子性操作,避免了使用锁带来的性能开销。

  3. ConcurrentSkipListSet 具有弱一致性的特性,即它允许在并发情况下读操作与写操作之间存在短暂的不一致。这使得在大多数情况下读操作不需要进行同步操作,从而提高了并发访问的效率。

?ConcurrentSkipListSet 是线程安全的数据结构,它通过跳表的层级结构和 CAS 操作来实现并发控制,保证了多线程并发访问时的原子性操作和性能。同时,它具有弱一致性的特性,避免了不必要的同步操作。

ConcurrentSkipListSet的实例

下面是一个使用ConcurrentSkipListSet的示例代码:

import java.util.concurrent.ConcurrentSkipListSet;

public class ConcurrentSkipListSetExample {
    public static void main(String[] args) {
        ConcurrentSkipListSet<Integer> set = new ConcurrentSkipListSet<>();

        // 添加元素
        set.add(1);
        set.add(2);
        set.add(3);

        // 遍历元素
        for (Integer num : set) {
            System.out.println(num);
        }

        // 删除元素
        set.remove(2);

        // 判断元素是否存在
        boolean contains = set.contains(3);
        System.out.println(contains);
    }
}

? ? ?使用ConcurrentSkipListSet的步骤如下:

  1. 创建ConcurrentSkipListSet对象:ConcurrentSkipListSet&lt;Integer> set = new ConcurrentSkipListSet&lt;>();
  2. 添加元素:set.add(element);
  3. 删除元素:set.remove(element);
  4. 判断元素是否存在:boolean contains = set.contains(element);
  5. 遍历元素:for (Integer element : set) { ... }

文章来源:https://blog.csdn.net/Flying_Fish_roe/article/details/135356935
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。