【数据类型】Collections.synchronizedMap 多线程Map,与HashMap的不同

一、Collections.synchronizedMap 简介

Collections.synchronizedMap 是 Java 中提供的工具方法,用于创建一个同步(线程安全)的 Map。它接受一个现有的 Map 对象,并返回一个通过同步包装后的 Map

下面是一个简单的示例:

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;public class SynchronizedMapExample {public static void main(String[] args) {// 创建一个普通的 HashMapMap<String, Integer> hashMap = new HashMap<>();// 使用 Collections.synchronizedMap 方法创建同步的 MapMap<String, Integer> synchronizedMap = Collections.synchronizedMap(hashMap);// 现在 synchronizedMap 就是一个线程安全的 Map 对象// 同步块示例synchronized (synchronizedMap) {// 在同步块中对 synchronizedMap 进行操作}}
}

二、Collections.synchronizedMap 实现原理,关键源码

1、基础原理

Collections.synchronizedMap 是通过返回一个线程安全的 Map 包装器来实现的,它在对 Map 进行修改操作时会使用同步块来确保线程安全。该方法的基本原理如下:

  • 封装原始 Map: synchronizedMap 方法接受一个 Map 对象作为参数,然后返回一个线程安全的封装器。封装器会保持对原始 Map 的引用。
  • 同步块: 在对 Map 进行修改的方法(例如put、remove等)中,使用同步块(synchronized)来确保同一时刻只有一个线程可以执行这些修改操作。

2、实现源码

Collections.synchronizedMap 的关键源码如下:

public class Collections {// ...public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {return new SynchronizedMap<>(m);}static class SynchronizedMap<K,V> implements Map<K,V>, Serializable {// ...// 内部封装的原始 Map 对象private final Map<K,V> m;// ...public V put(K key, V value) {// 同步块确保线程安全synchronized (mutex) {return m.put(key, value);}}public void clear() {// 同步块确保线程安全synchronized (mutex) {m.clear();}}// ... 其他方法也都使用同步块来确保线程安全// ...}
}

在上述代码中,SynchronizedMapCollections.synchronizedMap 返回的封装器类。它实现了 Map 接口,同时包含了一个内部封装的原始 Map 对象 m,以及一个共享的锁对象 mutex

3、关键原理和实现逻辑:

  • 同步块: 在 SynchronizedMap 的实现中,所有可能引起修改的方法都使用 synchronized (mutex)
    进行同步。这意味着同一时刻只有一个线程可以执行这些方法,从而确保了线程安全。
  • 内部封装: SynchronizedMap 通过持有一个原始 Map 对象 m 的引用,将修改操作委托给这个原始 Map 对象。通过这种方式,SynchronizedMap 实际上是对原始 Map 对象的一种包装。
  • 锁对象: mutex 是一个共享的锁对象,用于控制同步块的访问。这个锁对象的作用是确保在同一时刻只有一个线程可以执行关键代码块,从而保证了对 Map 的操作是线程安全的。这是一种简单粗暴但有效的方式,被称为悲观锁,因为它悲观地认为在并发环境中会有冲突,因此通过加锁来保护共享资源。在 Collections.synchronizedMap 中,mutex 的选择是 Collections.synchronizedMap 对象本身。

在 Collections.synchronizedMap 中,mutex 的选择是 Collections.synchronizedMap 对象本身,这是因为 Java 中的 synchronized 关键字是与对象关联的。当一个线程进入同步块时,它要获取的是这个对象的锁。因此,为了实现同步,需要使用一个对象作为锁。

Collections.synchronizedMap 是一个工具类,用于返回线程安全的 Map 对象。当你调用 Collections.synchronizedMap(map) 时,实际上是返回了一个包装后的 SynchronizedMap 对象,该对象持有了一个内部的原始 map 对象,并使用 synchronized 来确保对原始 map 的操作是线程安全的。为了保证线程安全,SynchronizedMap 内部使用了一个 mutex 对象,而这个 mutex 对象就是Collections.synchronizedMap 对象本身。这种选择是为了确保在对原始 map 进行操作时,所有需要同步的线程都是以同一个锁对象为基础的,这样才能够有效地实现线程安全。
总的来说,mutex 的选择是为了将 SynchronizedMap 包装后的对象作为一个整体来加锁,确保对原始 map
的修改操作是原子的,从而实现线程安全。

三、注意事项

需要注意的是,虽然 Collections.synchronizedMap 提供了线程安全的访问,但在高并发环境下,使用这种方式可能导致性能瓶颈。因为同步是在整个 Map 对象上进行的,当多个线程同时访问时,只有一个线程能够执行修改操作,其他线程必须等待。

在Java 5及之后的版本,推荐使用 ConcurrentHashMap 来获得更好的并发性能。 ConcurrentHashMap 在设计上采用了分段锁(Segment)的机制,允许多个线程同时修改不同的段,从而提高了并发性能。详情参考【数据类型】ConcurrentHashMap分段锁实现高并发;与HashMap的区别

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

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

相关文章

Springboot注解@Configuration和@Bean注解作用,生命周期

简介&#xff1a; Configuration 类是定义 bean 配置的地方&#xff0c;而 Bean 方法是具体创建 bean 实例的方法。 Configuration 作用&#xff1a; Configuration 注解用于定义配置类&#xff0c;表明该类包含一个或多个 bean 定义的方法。Spring 容器在启动时会自动扫描这些…

写一个判断鼠标进入方向切换图片的效果

直接看代码&#xff1a; <template><div class"mainrouter centerWindi"><div ref"mouse" class"mouse" mouseenter"handleMouse"></div></div> </template> <script setup> import { onMo…

erlang/OTP 平台(学习笔记)(四)

Erlang语言精要 Erlang shell 相较于日常惯用的系统&#xff0c;Erlang系统是一套更富交互性的环境。使用大部分编程语言时&#xff0c;要么把程序编译成OS可执行文件后运行&#xff0c;要么用解释器来执行一堆脚本文件或编译后的字节码文件。无论哪种情况&#xff0c;都是让…

LeetCode:82. 删除排序链表中的重复元素 II(C++、Java)

目录 82. 删除排序链表中的重复元素 II 题目描述&#xff1a; 实现代码与解析&#xff1a; 链表遍历&#xff1a; 实现代码与解析&#xff1a; 82. 删除排序链表中的重复元素 II 题目描述&#xff1a; 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复…

美颜技术对比:如何根据项目选择不同的美颜SDK?

各位开发者应该非常清楚&#xff0c;为了在项目中取得最佳效果&#xff0c;选择合适的美颜SDK至关重要。本篇文章&#xff0c;笔者将通过对比不同美颜SDK的关键特性&#xff0c;帮助开发者根据项目需求做出明智的选择。 一、技术原理对比 不同的美颜SDK可能采用不同的技术原理…

汽车线束的汽配企业MES管理系统解决方案

随着科技的飞速发展和环保需求的日益提升&#xff0c;新能源汽车在全球范围内崭露头角&#xff0c;成为未来出行的主导力量。在这股浪潮中&#xff0c;中国凭借其强大的研发实力和市场敏锐度&#xff0c;迅速崛起为新能源汽车领域的佼佼者。而作为汽车数字化控制与智能化应用的…

Unity中URP下的SimpleLit顶点着色器

文章目录 前言顶点着色器1、GPU Instance 相关2、顶点输入数据相关3、雾效混合因子4、对 uv 进行 Tilling 和 Offset 的应用 及 把顶点的坐标信息传给输出结构体5、把法线相关的结果&#xff0c;传给输出结构体6、光照贴图相关7、额外灯相关计算8、阴影相关 前言 在上一篇文章…

Git保姆级别的安装教程

Git保姆级别的安装教程 https://blog.csdn.net/m0_48170265/article/details/129303254 文章目录 一、Git下载 二、Git 的安装 用户许可声明选择安装目录选择安装组件选择开始菜单文件夹选择默认编辑器决定初始化新项目(仓库)的主干名字调整 path 环境变量选择 SSH 执行文件选…

elementui-树形控件实现子节点右侧添加图标和数据,鼠标放上去显示文字

1、代码 <el-treev-loading"nameLoding":data"data"node-key"id":highlight-current"true"empty-text"暂无数据":props"defaultPropsIndex"default-expand-all:filter-node-method"filterNodeIndex"…

LeetCode 226. 翻转二叉树

226. 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;[2,…

redis 从0到1完整学习 (十八):阻塞/非阻塞 IO

文章目录 1. 引言2. redis 源码下载3. I/O 模型3.1 阻塞 I/O3.2 非阻塞 I/O 4. 参考 1. 引言 前情提要&#xff1a; 《redis 从0到1完整学习 &#xff08;一&#xff09;&#xff1a;安装&初识 redis》 《redis 从0到1完整学习 &#xff08;二&#xff09;&#xff1a;red…

jetlinks 规则编排中的函数节点使用 js 脚本格式化输出当前系统时间的坑

网上搜到的都是类似如下这种&#xff1a; // 获取当前时间 var date new Date();// 格式化输出当前时间 var year date.getFullYear(); var month date.getMonth(); var day date.getDate(); var hour date.getHours(); var minute date.getMinutes(); var second date.…

捷为科技亮相2024深圳PMO年度论坛 探讨项目管理赋能企业数字化转型

1月13日&#xff0c;一场聚焦项目管理创新与数字化转型的盛会——2024年深圳PMO年度论坛在深圳新一代产业园隆重举行。本次论坛以“项目管理赋能企业数字化转型”为主题&#xff0c;汇聚了众多行业专家、学者和企业代表&#xff0c;共同探讨如何通过项目管理推动企业数字化转型…

电商概念之商品模型

1、基本定义 广义定义&#xff1a;商品是为了出售而生产的劳动成果&#xff0c;人类社会生产力发展到一定历史阶段的产物&#xff0c;用于交换的劳动产品。 电商商品基本概念&#xff1a; 商品类目商品属性销售属性商品编码&商品规格编码SKU和SPU… 2、商品类目 电商平…

【动态规划】20子数组系列_环形子数组的最大和_C++(medium)

题目链接&#xff1a;leetcode环形子数组的最大和 目录 题目解析&#xff1a; 算法原理 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 编写代码 题目解析&#xff1a; 题目让我们求返回 nums 的非空 子数组 的最大可能和 这道题如果是按照-这道题-是不对…

华为MindStudio简介

MindStudio是华为推出的一款集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于边缘计算和人工智能应用的开发。它为开发者提供了一系列工具&#xff0c;用于设计、开发、调试和部署在华为Ascend系列AI处理器上运行的应用程序。MindStudio旨在简化和加速AI应用开发的…

基于信号完整性的一些PCB设计建议

最小化单根信号线质量的一些PCB设计建议 1. 使用受控阻抗线&#xff1b; 2. 理想情况下&#xff0c;所有信号都应该使用完整的电源或地平面作为其返回路径&#xff0c;关键信号则使用地平面作为返回路径&#xff1b; 3. 信号的返回参考面发生变化时&#xff0c;在尽可能接近…

JMeter笔记(三)

个人学习笔记&#xff08;整理不易&#xff0c;有帮助点个赞&#xff09; 笔记目录&#xff1a;学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 目录 一&#xff1a;参数化方法 1&#xff09;用户定义的变量 2&#xff09;函数助手 3&#xff09;…

MYSQL的事务隔离

本章概览 mysql是一个支持多引擎的系统&#xff0c;并不是所有引擎都支持事务&#xff0c;本篇以innodb为例解析mysql在事务支持的实现。提到事务一定会想到ACID(Atomicity、Consistency、Isolation、Durability&#xff0c;即原子性、一致性、隔离性、持久性)&#xff0c;今天…

(二)如何在两台运行Ubuntu 20.04的系统上建立RabbitMQ集群

如何在两台运行Ubuntu 20.04的系统上建立RabbitMQ集群。建立RabbitMQ集群需要一些特定的步骤&#xff0c;下面是一个概述&#xff1a; 安装RabbitMQ和Erlang&#xff1a;首先&#xff0c;在两台服务器上都执行您提供的快速安装脚本以安装RabbitMQ和Erlang。 详见《(一)Ubuntu 2…