线程安全的集合类(多线程环境下使用ArrayList、队列及哈希表)

news2024/12/30 3:15:26

目录:

多线程环境下使用ArrayList

多线程环境下使用队列

多线程环境下使用哈希表


多线程环境下使用ArrayList

在多线程环境下使用ArrayList可以有以下三种方式:

1.使用同步机制 (synchronized 或者 ReentrantLock)

2.Collections.synchronizedList(new ArrayList),synchronizedList 是标准库提供的一个基于synchronized 进行线程同步的 List,synchronizedList 的关键操作上都带有 synchronized,使用这个方法把集合类套一层。

3.使用 CopyOnWriteArrayList

CopyOnWrite容器即写时复制的容器,简称“COW”,也叫做“写时拷贝”。如果针对这个ArrayList进行读操作,不做任何额外的工作。如果进行写操作,则拷贝一份新的ArrayList,针对新的进行修改,修改过程中如果有读操作,就继续读旧的这份数据。当修改完毕了,使用新的替换旧的(本质上就是一个引用之间的赋值,是原子的)。

很明显,这种方案,优点是不需要加锁,不需要锁竞争,在读多写少的场景下的性能很高;缺点则是要求这个ArrayList不能太大,否则占用内存太大,而且新写的数据不能第一时间被读到。

多线程环境下使用队列

1) ArrayBlockingQueue 基于数组实现的阻塞队列

2) LinkedBlockingQueue 基于链表实现的阻塞队列

3) PriorityBlockingQueue 基于堆实现的带优先级的阻塞队列

4) TransferQueue 最多只包含一个元素的阻塞队列

TransferQueue 的应用场景是,当不想生产者过度生产消息时,TransferQueue可能非常有用,在这样的设计中,消费者的消费能力将决定生产者产生消息的速度。

多线程环境下使用哈希表

HashMap 本身不是线程安全的,在多线程环境下使用哈希表可以使用:Hashtable和ConcurrentHashMap

Hashtable是线程安全的,它是在关键方法上加了synchronized。更推荐使用的是ConcurrentHashMap,它是更优化的线程安全哈希表。

ConcurrentHashMap进行了哪些优化?比HashTable好在哪里?和HashTable之间的区别是啥?

1.最大的优化之处:ConcurrentHashMap相比于HashTable 大大缩小了锁冲突的概率,把一把大锁,转换成多把小锁了。

HashTable的做法是直接在方法上加synchronized,等于是给this加锁,只要操作哈希表上的任意元素,都会产生加锁,也就都可能会发生锁冲突。但是实际上,基于哈希表的结构特点,有些元素在进行并发操作的时候,是不会产生线程安全问题的,也就不需要使用锁控制。

此时元素1和元素2在同一链表上,如果线程A修改(增删)元素1,线程B修改元素2,那么此时是有线程安全问题的(相邻两元素并发的插入或者删除的时候,相邻两节点的next指向可能会发生改变)。如果线程A修改(增或者删)元素3,线程B修改元素4,,这个情况相当于多个线程修改不同的变量,那么此时是没有线程安全问题的。

使用HashTable,锁冲突概率就太大了,任何两个元素的操作都会有锁冲突,即使是处在不同的链表上,这就是不用HashTable的主要原因。

ConcurrentHashMap做法是,每个链表有各自的锁(而不是大家共用同一个锁了),具体来说,就是使用每个链表的头结点,作为锁对象(两个线程针对同一个锁对象加锁才有锁竞争,才有阻塞等待,针对不同对象,没有锁竞争)。

此时,把锁的粒度变小了,针对12这个情况,是针对同一把锁进行加锁,会有锁竞争,会保证线程安全。针对34这个情况,是针对不同的锁进行加锁,不会有锁竞争了,没有阻塞等待,程序就会更快。

2.针对读操作,不加锁,只针对写操作加锁

读和读之间没有冲突;写和写之间有冲突,可以加锁;读和写之间没有冲突,但是很多场景下,读写之间不加锁控制,如果写操作不是原子的,那么会产生脏读,所以使用了 volatile 保证了原子性。

3.ConcurrentHashMap内部充分的使用了CAS,通过这个也来进一步的削减加锁操作的数目

4.针对扩容,采取了"化整为零"的方式

HashMap/HashTable扩容:

创建一个更大的数组空间,把旧的数组上的链表上的每个元素搬运到新的数组上(删除+插入),这个扩容操作会在某次put 的时候进行触发。如果元素个数特别多,就会导致这样的搬运操作,比较耗时。

ConcurrentHashMap 中,扩容采取的是每次搬运一小部分元素的方式。创建新的数组,旧的数组也保留。每次 put 操作,都往新数组上添加,同时进行一部分搬运(把一小部分旧的元素搬运到新数组上)。每次get的时候,则旧数组和新数组都查询。每次remove 的时候,只是把元素删了就行了。经过一定时间之后,所有的元素都搬运好了,最终再释放旧数组。

小结:

Hashtable和HashMap、ConcurrentHashMap 之间的区别?

HashMap: 线程不安全. key 允许为 null

Hashtable: 线程安全,使用 synchronized 锁 Hashtable 对象, 效率较低,key 不允许为 null

ConcurrentHashMap: 线程安全,使用 synchronized 锁每个链表头结点, 锁冲突概率低, 充分利用

CAS 机制,优化了扩容方式,key 不允许为 null

ConcurrentHashMap在jdk1.8做了哪些优化?

取消了分段锁, 直接给每个哈希桶(每个链表)分配了一个锁(就是以每个链表的头结点对象作为锁对象)。将原来 数组 + 链表 的实现方式改进成 数组 + 链表 / 红黑树 的方式,当链表较长的时候(大于等于

8 个元素)就转换成红黑树。

PS:分段锁是 Java1.7 中采取的技术,Java1.8 中已经不再使用了,简单的说就是把若干个哈希桶分成一个

"段", 针对每个段分别加锁,目的也是为了降低锁竞争的概率。当两个线程访问的数据恰好在同一个段上的时候, 才触发锁竞争。

ConcurrentHashMap的读是否要加锁?

读操作没有加锁,目的是为了进一步降低锁冲突的概率,为了解决脏读,保证读到刚修改的数据, 搭配了

volatile 关键字。

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

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

相关文章

Python __slots__:限制类实例动态添加属性和方法

那么,Python 是否也允许动态地为类或实例对象添加方法呢?答案是肯定的。我们知道,类方法又可细分为实例方法、静态方法和类方法,Python 语言允许为类动态地添加这 3 种方法;但对于实例对象,则只允许动态地添…

相机标定与3D重建(3)使用OpenCV对摄像机进行标定

相机已经存在很长很长时间了。然而,随着20世纪末廉价针孔相机的出现,针孔相机在我们的日常生活中司空见惯。不幸的是,这种廉价是有代价的:严重的扭曲。幸运的是,这些都是常量,通过标定和一些重新映射,我们可…

WebDAV之葫芦儿·派盘+GeniusScan

GeniusScan 支持WebDAV方式连接葫芦儿派盘。 推荐一款功能极其强大的手机微型扫描仪软件,可以将所有的东西扫描成为pdf格式的文档,还支持连接葫芦儿派盘服务。 GeniusScan让您的安卓设备变身微型扫描仪。它能让您快速扫描文档,将扫描结果保存JPEG或PDF格式,

【数字化】要点整理-《数据治理体系完整指南》

导读:本文整理内容来自一篇关于数据治理体系相对比较完整内容文章,体系化的范围介绍主要包括了介绍元数据、数据标准、数据建模、数据集成、数据质量、数据开发、数据安全、ETL。可以作为数据治理建设参考。01 数据治理体系02 元数据2.1、元数据解决的问…

先天性心脏病的6大症状,家长要重视治疗!

先天性心脏病是一种严重的心血管疾病,与遗传和环境有密切的关系,而且先天性心脏病越早治疗效果越好,因此要了解先天性心脏病的相关症状,能够更早的确诊病情,并提高患者的治愈几率。 天天性心脏病有哪些症状&#xff1f…

【链表面试题考察】

以下题目均为IO型。1.给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。题目示例如上:解题思路:双指针问题,给定指针prev和cur,从头结点开始往…

Unity SKFramework Documentation

文章目录Audio 音频背景音乐音效音频库Audio ListenerActions 事件Action 事件类型Action Chain 事件链Sequence 序列事件链Concurrent 并发事件链Timeline 时间轴事件链FSM 有限状态机State 状态State Machine 状态机State Builder 状态构建器ObjectPool 对象池IPoolable 接口…

2023 年 1 月的5篇深度学习论文推荐

本文整理了 2023 年 1 月5 篇著名的 AI 论文,涵盖了计算机视觉、自然语言处理等方面的新研究。 InstructPix2Pix: Learning to Follow Image Editing Instructions https://arxiv.org/abs/2211.09800v2 伯克利分校的研究人员开发了一种使用人工指令编辑图像的新方…

小程序项目学习--**第三章:WXSS-WXML-WXS语法**事件处理-组件化开发

第三章&#xff1a;WXSS-WXML-WXS语法事件处理-组件化开发 01_(掌握)WXML语法-基本规则和mustache语法 Page({data: {message: "Hello World",firstname: "kobe",lastname: "bryant",date: new Date().toLocaleDateString(),}, }) <!-- 1.Mu…

【HBase高级】5. HBase数据结构(上)跳表、二叉搜索树、红黑树、B、B+树

4. HBase事务 HBase 支持特定场景下的 ACID&#xff0c;即当对同一行进行 Put 操作时保证完全的 ACID。可以简单理解为针对一行的操作&#xff0c;是有事务性保障的。HBase也没有混合读写事务。也就是说&#xff0c;我们无法将读操作、写操作放入到一个事务中。 5. HBase数据…

CMMI高效落地 4大关键点要注意

CMM对企业降本增效、增强竞争力方面&#xff0c;优势明显。那么如何顺利进行CMMI认证&#xff1f;我们在CMMI认证时&#xff0c;需要注意哪些方面&#xff1f; 1、公司高层的支持 一个公司过程改进 工作的顺利施行&#xff0c;首先需要公司高层的支持。公司的商业目标、公司高层…

45_API接口漏洞

API接口漏洞 一、概念 api > application interface 应用接口 向特定的接口发送一个请求包 返回一个类似于json格式的字符串 二、REST型web service 可以从网上去搜索下api接口去理解,下面有个我找到的网址,给出api接口的分类 https://blog.csdn.net/t79036912/article…

【顺序表和链表的对比】

前言&#xff1a; 我们已经学习过了顺序表和链表的一些知识&#xff0c;在实际运用中我们不能笼统的说哪种存储结构更好&#xff0c;由于它们各有优缺点&#xff0c;选择哪种存储结构&#xff0c;则应该根据具体问题作出具体的分析&#xff0c;通常从空间性能和时间性能上作比较…

Day14【元宇宙的实践构想03】—— 元宇宙的资产观(NFT、数字资产、虚拟地产、与现实世界资产关系)

&#x1f483;&#x1f3fc; 本人简介&#xff1a;男 &#x1f476;&#x1f3fc; 年龄&#xff1a;18 ✍今日内容&#xff1a;《元宇宙的实践构想》03——元宇宙的资产观 ❗❗❗从1.31日开始&#xff0c;阿亮每天会查阅一些元宇宙方面的小知识&#xff0c;和大家一起分享。一是…

cobaltstrike的shellcode免杀

基础概念 shellcode是一段用于利用软件漏洞而执行的代码&#xff0c;也可以认为是一段填充数据&#xff0c;shellcode为16进制的机器码&#xff0c;因为经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。 可在暂存器eip溢出后&#xff0c;塞入一段可让CPU执行的s…

vue入门到精通(七)

6、依赖注入 祖先组件向后代组件传值 6.1 provide() 提供一个值&#xff0c;可以被后代组件注入。 provide() 接受两个参数&#xff1a;第一个参数是要注入的 key&#xff0c;可以是一个字符串或者一个 symbol&#xff0c;第二个参数是要注入的值。 与注册生命周期钩子的 AP…

百趣代谢组学文献分享埃博拉病毒发病机制及组合生物标志物的发现

百趣代谢组学文献分享&#xff0c;今天我们分享的文献就是通过多组学技术研究埃博拉病毒发病机制及组合生物标志物的发现。该文献的研究思路也可以给我们开展新型冠状病毒肺炎相关研究提供借鉴。 代谢组学文献分享&#xff0c;2013-2016年西非埃博拉病毒病&#xff08;EVD&…

(面经三,技术面)——时间:2022-11-11 地点:线上

面试经历&#xff08;三&#xff09;——时间&#xff1a;2022-11-11 地点&#xff1a;线上 1.什么是抽象类 有抽象方法的类&#xff0c;用来表征对问题领域进行分析、设计中得出的抽象概念。 2.抽象类和接口的区别 继承关系&#xff1a;类只能单继承。接口可以实现多个接口 构…

智慧物业管理系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

【大数据】第二章:搭建Hadoop集群(送尚硅谷大数据笔记)

尚硅谷Hadoop3.x官方文档大全免费下载 搭建集群没什么好讲的&#xff0c;跟着视频和笔记出不了什么问题。 唯一遇到的问题就是安装好VmWare后打不开&#xff0c;发现是老师给的VmWare版本不适配本机的WIN11。 解决办法就是下载最新版本的VmWare。新版已经修复了与WIN11的兼容性…