Java 入门指南:Java 并发编程 —— 并发容器 ConcurrentSkipListMap

news2024/9/22 23:35:13

ConcurrentMap

ConcurrentMap 是 Java 并发包中提供的一个接口,它继承了 java.util.Map 接口,专门用于支持高并发环境下的线程安全操作。ConcurrentMap 提供了一系列线程安全的方法,旨在解决在多线程环境下使用普通 Map 类型(如 HashMap)时可能出现的竞态条件和数据不一致问题。
在这里插入图片描述

ConcurrentMap 具有以下特点:

  1. 线程安全性ConcurrentMap 中的方法都是线程安全的,可以在多线程环境中安全地使用,无需额外的同步措施。

  2. 高并发性能ConcurrentMap 的设计目标是在高并发环境下提供高性能的操作,尤其适用于读多写少的场景。

  3. 原子性操作:提供了一系列原子性操作,如 putIfAbsentremove 等,这些操作在执行时不会被其他线程干扰。

常见实现

ConcurrentMap 接口有多种实现,其中最常见的是 ConcurrentHashMap。其他实现还包括 ConcurrentSkipListMap 等。

  • ConcurrentHashMap

    • 在 Java 8 之前,ConcurrentHashMap 使用了锁分段技术(segment-based locking),将哈希表分割成多个段,每个段有自己的锁,从而允许多个写入操作并发进行。
    • 在 Java 8 中,ConcurrentHashMap 采用了基于 CAS(Compare and Swap)操作的新实现,提供了更高的并发性能。
  • ConcurrentSkipListMap

    • 使用跳表(Skip List)作为底层数据结构,提供了有序的键值对存储,适合需要排序操作的场景。

方法

ConcurrentMap 接口提供了以下常用方法(除了一些 Map 基本方法):

  1. V get(Object key):获取指定键对应的值,如果映射表中不存在该键,则返回 null。

  2. V put(K key, V value):将指定键值对插入到映射表中,如果这个键已经存在,则用新值替换旧值,并返回旧值。如果插入一个 null 的键或值,则抛出 NullPointerException

  3. putIfAbsent(K key, V value):如果指定的键(key)不存在,则将键值对插入到映射表中;如果键已经存在,则不进行插入操作,并返回原先的值。

  4. boolean remove(Object key, Object value):如果指定的键值对存在,则从映射表中删除该键值对;否则不进行任何操作。

  5. boolean replace(K key, V value):替换指定键的值,无论该键原来的值是什么,都会执行替换操作。

  6. boolean replace(K key, V oldValue, V newValue):以原子方式将键值对由旧值替换为新值,即只有在该键原来的值和提供的旧值(oldValue)相等时,才会执行替换操作。。

  7. int size():返回映射表中键值对的数量。

  8. V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction):如果指定键没有关联值,将通过运行映射函数来计算一个新的值,并将该键关联到该计算值。

  9. V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction):如果指定键已经具有相关联的值,则通过运行重新映射函数来计算一个新值,并将该键关联到该值。在计算过程中,更新可能会顺便修改现有映射,从而避免了常见的条件费用。

  10. V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction):原子性的操作,它能够在并发环境中安全地更新或计算指定键的值。

    key:要更新或计算值的键。remappingFunction:用于更新或计算值的函数。

    remappingFunction 是一个在并发操作中被调用的函数,它接受两个参数:当前键的值(如果存在)和当前键。通过这个函数,可以基于当前的值来计算新的值。remappingFunction 的返回值将作为新的值存储在 ConcurrentHashMap 中,若返回 null,则会删除当前键。

  11. void forEach(BiConsumer<? super K, ? super V> action):对映射表中的每个键值对执行给定的动作。

  12. V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction):如果指定的键已存在,将其关联的值与给定的合并函数合并,如果不存在,则将其关联到给定值。

  13. default V getOrDefault(Object key, V defaultValue):获取指定键的值,如果键不存在,则返回默认值。可以用于避免空指针异常。

ConcurrentNavigableMap

ConcurrentNavigableMap 是 Java 并发包中的一个接口,它扩展了 ConcurrentMap 接口,并支持导航(查找和遍历)的功能。它允许多个线程同时访问和修改映射表,同时提供了按照键排序的功能。

ConcurrentNavigableMap 实现了一种有序的键值映射表,可以使用键的自然顺序或自定义的比较器对键进行排序。这些特性使得其特别适用于需要按照键进行范围查找和迭代的情况

ConcurrentNavigableMap 的常见实现类是 ConcurrentSkipListMap,它基于跳表(Skip List)数据结构实现了 ConcurrentNavigableMap 接口。

常用方法

  • lowerKey(K key): 返回小于给定键的最大键,如果不存在则返回 null。

  • floorKey(K key): 返回小于等于给定键的最大键,如果不存在则返回 null。

  • ceilingKey(K key): 返回大于等于给定键的最小键,如果不存在则返回 null。

  • higherKey(K key): 返回大于给定键的最小键,如果不存在则返回 null。

  • subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive): 返回一个包含指定范围的子映射。

  • headMap(K toKey, boolean inclusive): 返回小于等于给定键的部分映射。

  • tailMap(K fromKey, boolean inclusive): 返回大于等于给定键的部分映射。

  • descendingMap(): 返回一个逆序的视图,按键的降序排列。

以上这些方法提供了对映射表进行范围查找和操作的能力。

ConcurrentSkipListMap

ConcurrentSkipListMap 是 Java 中的一个线程安全集合类,实现了ConcurrentMap 接口。它支持高效的插入、删除和查找操作,并提供了强一致性、线程安全的操作保证。

ConcurrentSkipListMap 底层基于跳表,每个节点包含一个键值对多个指向下一个节点的指针

在插入、删除、查找元素时,ConcurrentSkipListMap从节点的最高层级开始查找,并逐层降低层级,直到找到对应的节点或无法继续降低层级。可以在高并发环境下提供高效的查找、插入、删除操作,并且保证线程安全或强一致性。

ConcurrentSkipListMap 要求键必须实现 Comparable 接口或提供自定义的 Comparator 比较器,以便进行按键排序。

在使用 ConcurrentSkipListMap 时,需要注意元素的相等、哈希等条件,以确保操作的正确性。

特点

ConcurrentSkipListMap 的特性如下:

  1. 线程安全:ConcurrentSkipListMap 支持多线程的并发访问,保证了线程安全性。

  2. 有序键值对映射:ConcurrentSkipListMap 继承了 SortedMap 接口,保证了有序的键值对映射集合。

  3. 可能存在重复的键:ConcurrentSkipListMap 可以存在相同的键,因此在插入键值对时需要注意。

  4. 高效的插入、删除和查找操作:ConcurrentSkipListMap 采用跳表的数据结构,在高度平衡与高效性之间取得了一个良好的平衡,具有较高的速度。

构造方法
  1. 创建一个空的 ConcurrentSkipListMap,使用键的自然顺序进行排序。
ConcurrentSkipListMap()
  1. 创建一个空的 ConcurrentSkipListMap,使用指定的比较器对键进行排序。
ConcurrentSkipListMap(Comparator<? super K> comparator)
ConcurrentSkipListMap<String, Integer> map = new ConcurrentSkipListMap<>(Comparator.comparingInt(String::length));
  1. 创建一个包含指定映射中所有映射关系的 ConcurrentSkipListMap
ConcurrentSkipListMap(Map<? extends K, ? extends V> m)
  1. 创建一个与指定排序映射有相同映射关系的 ConcurrentSkipListMap
ConcurrentSkipListMap(SortedMap<K, ? extends V> m)
常用方法
  1. put(K key, V value):将指定的键值对添加到映射中,如果键已经存在,则将其对应的值替换为新值。

  2. remove(Object key):从映射中移除指定键的键值对。

  3. get(Object key):获取给定键所对应的值,如果键不存在则返回null。

  4. containsKey(Object key):判断映射中是否包含指定的键,返回布尔值。

  5. isEmpty():判断映射是否为空,如果为空则返回true,否则返回false。

  6. size():返回映射中键值对的数量。

  7. keySet():返回一个包含映射中所有键的 Set 集合。

  8. values():返回一个包含映射中所有值的 Collection 集合。

  9. entrySet():返回一个包含映射中所有键值对的 Set 集合。

  10. firstKey():返回映射中的第一个键。

  11. lastKey():返回映射中的最后一个键。

  12. subMap(K fromKey, K toKey):返回一个子映射,包含所有在给定范围内的键值对。

  13. headMap(K toKey):返回一个子映射,包含所有小于给定键的键值对。

  14. tailMap(K fromKey):返回一个子映射,包含所有大于等于给定键的键值对。

  15. clear():清空映射,移除所有的键值对。

ConcurrentSkipListMap 使用示例

下面是使用 ConcurrentSkipListMap 的代码示例

import java.util.concurrent.ConcurrentSkipListMap;

public class ConcurrentSkipListMapExample {

    public static void main(String[] args) {
        // 创建一个 ConcurrentSkipListMap 实例
        ConcurrentSkipListMap<Integer, String> skipListMap = new ConcurrentSkipListMap<>();

        // 插入键值对
        skipListMap.put(3, "Three");
        skipListMap.put(1, "One");
        skipListMap.put(4, "Four");
        skipListMap.put(2, "Two");

        // 输出键值对
        System.out.println("Initial Map: " + skipListMap);

        // 获取键值对
        String value = skipListMap.get(3);
        System.out.println("Value of '3': " + value);

        // 判断是否存在键
        boolean contains = skipListMap.containsKey(5);
        System.out.println("Contains '5': " + contains);

        // 使用 putIfAbsent
        String newValue = skipListMap.putIfAbsent(5, "Five");
        System.out.println("Put or existing value of '5': " + newValue);

        // 使用 computeIfAbsent
        String computedValue = skipListMap.computeIfAbsent(6, k -> "Six");
        System.out.println("Computed value of '6': " + computedValue);

        // 使用 replace
        boolean replaced = skipListMap.replace(5, "Five", "New Five");
        System.out.println("Replaced '5' with 'New Five': " + replaced);

        // 遍历所有键值对
        skipListMap.forEach((key, val) -> System.out.println("Key: " + key + ", Value: " + val));

        // 使用 headMap 和 tailMap
        System.out.println("Head Map (up to 3): " + skipListMap.headMap(3));
        System.out.println("Tail Map (from 3): " + skipListMap.tailMap(3));

        // 使用 subMap
        System.out.println("Sub Map (from 2 to 4): " + skipListMap.subMap(2, 4));

        // 清空映射
        skipListMap.clear();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2101490.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用ChatGPT三分钟写一个完美的PPT,彻底告别繁琐的制作过程

用AI或ChatGPT来制作PPT的方式多得很&#xff01; 下面就用超级简单的语言&#xff0c;一步步教你怎么搞定&#xff0c;三分钟内保准搞定你的PPT。 所有需要的方法和工具都在这里&#xff01; 很简单&#xff0c;只要你输入一个标题&#xff0c;AI就能完成PPT的制作。 如果…

文件 fd

目录 1. 建立共识原理2. 回忆 C 文件接口2.1 当前工作路径2.2 w / a 方式写入2.3 默认打开的三个文件流 3. 认识文件系统调用3.1 O_WRONLY|O_CREAT 写时创建3.2 O_TRUNC 截断长度&#xff08;也即全覆盖式写入&#xff09;3.3 O_APPEND 追加 4. 浅谈文件访问的本质4.1 简证 1. …

高级算法设计与分析 学习笔记 2 希尔排序 线性时间内的排序——计数排序,基数排序,桶排序

希尔排序&#xff08;比较排序&#xff09; 要选定一个步长&#xff08;比如4&#xff09;&#xff0c;那么0&#xff0c;4&#xff0c;8……它们是一组&#xff0c;1&#xff0c;5&#xff0c;9……他们是一组。分组排完之后再换成2步长&#xff0c;最后改成1&#xff0c;就行…

牛心包瓣类医用生物瓣膜厚度无损检测

关键字&#xff1a;牛心包瓣膜&#xff0c;牛心包瓣叶&#xff0c;生物瓣膜&#xff0c;生物心脏膜&#xff0c;测厚仪&#xff0c;瓣膜生产&#xff0c;瓣膜检测设备&#xff0c; 牛心包瓣叶的厚度和轮廓所需的高精度取决于多个因素&#xff0c;包括瓣膜的制造标准、临床应用需…

百度飞将 paddle ,实现贝叶斯神经网络 bayesue neure network bnn,aistudio公开项目 复现效果不好

论文复现赛&#xff1a;贝叶斯神经网络 - 飞桨AI Studio星河社区 https://github.com/hrdwsong/BayesianCNN-Paddle 论文复现&#xff1a;Weight Uncertainty in Neural Networks 本项目复现时遇到一个比较大的问题&#xff0c;用pytorch顺利跑通源代码后&#xff0c;修改至pad…

【每日一练】python之tkinter的Label标签基础用法

""" 什么是tkinter窗口&#xff1f;tkinter是python中一个标准的库&#xff0c;用于创建图形界面&#xff08;GUI&#xff09;应用程序&#xff0c;它提供了一组工具和组件&#xff0c;使开发者能够在Python中创建窗口、按钮、标签、文本框、菜单等各种界面元素…

基于协同过滤的电影推荐系统

推荐系统已经成为当今互联网平台不可或缺的一部分&#xff0c;尤其是在电影、音乐和电子商务等领域。本文将带您深入探讨如何利用协同过滤算法&#xff0c;构建一个功能齐全的电影推荐系统。我们将结合Python、Django框架以及协同过滤算法&#xff0c;逐步实现这一目标。 完整…

Go父类调用子类方法(虚函数调用)

前言 在Go语言中&#xff0c;支持组合而不是继承。网上都说可以通过接口和结构体内嵌来模拟面向对象编程中的子类和父类关系。但给的例子或写法感觉都不是很好&#xff0c;难以达到我的目的&#xff08;比如通过模板模式实现代码的重用等&#xff09;。因此调查了一下实现方式…

内裤洗衣机需要一人一台吗?快来围观2024年五大好货集合

随着市面上的内衣抑菌产品越来越多&#xff0c;内衣洗衣机的质量也是参差不齐&#xff0c;一些网红跨界品牌内衣洗衣机的用料和做工品质较差&#xff0c;使用过程中出现清洗不干净和稳定性不足等问题。那么选购内衣洗衣机需要注意什么呢&#xff1f;我作为一名小家电测评博主&a…

pikachu文件包含漏洞靶场(本地文件包含+远程文件包含关卡)

本地文件包含 1.来到关卡随便点击一个提交 可以发现这里可以读取文件 这是1.txt内容 能读取到上一级文件那么也就可以读取本地文件 上传一个jpg文件 拿去连就ok了 远程包含 包含写木马的文件 该文件内容如下&#xff0c;其作用是在fi_remote.php文件的同级目录下新建一个文…

Java 基于微信小程序的小区服务管理系统,附源码

博主介绍&#xff1a;✌stormjun、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

【赵渝强老师】MongoDB的WiredTiger存储引擎

WiredTiger提供文档级别&#xff08;Document-Level&#xff09;的并发控制&#xff0c;检查点&#xff08;CheckPoint&#xff09;&#xff0c;数据压缩和本地数据加密&#xff08; Native Encryption&#xff09;等功能。从MongoDB 3.2 版本开始&#xff0c;WiredTiger成为Mo…

大带宽服务器推流延迟怎么回事

大带宽服务器推流延迟的原因可能涉及多个方面&#xff0c;包括编码解码的延迟、网络传输延迟、CDN分发延迟以及播放端的缓冲处理等。下面将详细解释各个影响因素&#xff0c;并提出相应的优化建议&#xff1a; 1. 编码解码的延迟 视频编码格式的影响&#xff1a;不同的编码格式…

net、udp、tcp

Makefile的main.c文件中的全局变量SONG song,要在fun.c文件里面写成extern SONG song 编译方法 第一次编写 或 网络编程 物理层的网线规定有八根,颜色不一样,功能不一样,光猫把光信号转换成电信号,光纤10Gb WiFi叫无线局域网,一般也就50米左右,手机流量叫蜂窝网络,…

无限延展(倒推法)

本题不妨逆推。 对于长度为的字符串 ,若要求第位的延展,考虑 在最后一次延展前的位置。 若延展结束后的长度为,每次考虑以下内容: 若 ​,说明本次伸展无效, ,

CTFHub技能树-备份文件下载-bak文件

当开发人员在线上环境中对源代码进行了备份操作&#xff0c;并且将备份文件放在了 web 目录下&#xff0c;就会引起网站源码泄露。 使用dirsearch扫描出index.php.bak 有些时候网站管理员可能为了方便&#xff0c;会在修改某个文件的时候先复制一份&#xff0c;将其命名为xxx.b…

没关系,会一手Git版本控制就行(全)

Git版本控制 文章目录 Git版本控制1. 版本控制1.1 概述1.2 版本控制优点1.3 本地版本控制系统&#xff08;离线版&#xff09;1.4 集中化的版本控制系统&#xff08;联网版&#xff09;1.5 分布式版本控制系统&#xff08;离线联网版&#xff09; 2. Git概述2.1 Git基本工作流程…

BUUCTF PWN wp--ciscn_2019_n_8

第一步 checksec一下&#xff0c;本题为32位。 分析一下保护机制&#xff1a; 一、RELRO: Partial RELRO Partial RELRO 提供了一定程度的保护。在这种情况下&#xff0c;部分重定位表在程序启动时被设置为只读。这可以防止一些针对重定位表的攻击&#xff0c;比如通过篡改重…

Elasticsearch 介绍

1、课程介绍 1.1 ES 8.x 演化进程 版本号发布日期多少个次要版本迭代历时8.02022年2月11日&#xff1f;至今7.02019年4月11日17个次要版本34个月6.02017年11月15日8个次要版本17个月5.02016年10月27日6个次要版本13个月 2、Elasticsearch 是什么 2.1 概念 2.1.1 标准定义 …

QLineEdit中文本显示不全,部分字符显示空白问题

环境 QT5.14.2 Windows 7 现象 触发某个条件后&#xff0c;使用QLineEdit的setText方法设置文本后&#xff0c;文本部分字符缺失&#xff0c;现象如下&#xff08;小数点后都是4位&#xff09;&#xff1a; 解决办法 设置根据显示器的像素密度进行自动缩放&#xff1b;再主…