Java中的集合类与线程安全的讨论

1.ArrayList

ArrayList是线程不安全的,可以在单线程中使用,在多线程中可以根据代码选择合适的时机进行加锁,实现线程安全的操作,但对代码能力要求较高。

2.Collections.synchronizedList(new ArrayList)

返回的List中的关键操作上都带有synchronized,但由于加锁较多,使得锁冲突发生的效率较高,代码阻塞的概率较大,对性能会有一定的影响。

3.CopyOnWriteArrayList

CopyOnWrite即写时拷贝,当我们在修改变量的同时进行变量的读取时,使用写时拷贝会降低线程安全问题;

现有如下需求,将arrayList1中的值进行修改,

 

当我们进行简单的修改操作并同时进行数据的读取,这时就会出现下面的结果:100, 200,  3,4,5,这样的结果显然不是我们向读到的,这属于半修改状态的数据,于是可以使用写时拷贝。

现有一个引用指向arrayList1,当我们进行数据的修改时,就会创建出另一个新的顺序表arrayList2,在将新的数据写入到arrayList2中时,若需要进行读数据操作,这时就会只读取arrayList1中的数据,这样读到的数据就会全部都是旧的数据,这样就不会出现读取到半新半旧的数据,当数据全部写入完后,就会将引用指向arrayList2,这样就完成了多线程下的数据修改操作,并且不会引发线程安全问题。

虽然数据的复制与更新不是原子的,但由于在修改完成之前保存了旧的数据,就不会影响数据的读取;当数据修改完成后,引用的赋值时原子的,,也不会引发线程安全问题。

但上述方案也会有明显的问题:

1)当数据量很大时,拷贝的时间就会非常长,效率低下;

2)当有多个线程进行数据的修改操作时,也会引发线程安全问题,因为在修改完成后引用指向哪个修改完的顺序表是不确定的,这样就会导致修改的数据可能达不到自己想要的状态,而上述的写时拷贝操作也仅仅是两个线程之间的操作,一个读一个修改。

4.阻塞队列

ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue均是线程安全的。

5.HashMap

HashMap在不涉及线程安全的操作时效率非常高,但无法避免线程安全问题。

6.Hashtable

Hashtable是线程安全的,但由于他的每一个public方法均使用synchronized修饰,并且只有一把锁,导致容易发生锁冲突,导致线程阻塞的概率大,效率较低。

7.ConcurrentHasshMap

这个是线程安全的,并且针对桶级别进行加锁,效率更高。

对于一般的哈希表,当发生哈希冲突时,有两种解决方案:

1)线性探测,但是这种方法效率较低,不推荐使用;

2)链表,将会引发哈希冲突的数据放到链表上,效率更高,推荐使用,如下图:

对于HashMap,在多线程操作中当我们涉及到以下操作时会引发线程安全问题:

1)修改一个链表上的同一个值;

2)修改同一个链表上的两个元素,如在一个数后插入两个元素,一个线程插入一个;

3)修改HashMap的size等......

于是我们可以进行加锁操作,但不能向Hashtable一样,只是用一个锁并且将所有的public方法加上synchronized,我们可以针对每一个链表进行加锁操作,每一个链表使用不同的锁对象,这样就能有效地减少所冲突地概率,并且发生上述地1、2情况时会避免线程安全问题,进行线程阻塞;

但由于链表的个数可能会很多,导致锁对象地开销较大,在java中,锁对象可以是任意对象,于是可以使用每一个链表的头节点作为锁对象,这样就会减少锁对象的空间消耗。

但对于情况3,可以对size单独加锁,但这种解决方式不是最好的,我们可以使用原子类来代替size,即创建AtomicInteger对象来代表size,代码如下:

AtomicInteger size = new AtomicInteger(0); //0为初始值size.getAndIncrement(); //相当于size++size.incrementAndGet(); //相当于++sizeszie.addAndGet(n); //相当于size+=n

上述的三个针对size的操作均是原子的,是线程安全的;

对ConcurrentHasshMap进行扩容时,需要将原有的数据复制到新的哈希表中,当数据量较大时,一次复制所有的数据所需要的时间和空间开销都非常大,效率低下,于是可以分批次复制,一次只复制所有数据的百分之几,之后的每一次操作都会触发复制操作,几次之后就能完成数据的复制,这样的效率更高。

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

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

相关文章

【数据结构】线性表——栈与队列

写在前面 栈和队列的关系与链表和顺序表的关系差不多,不存在谁替代谁,只有双剑合璧才能破敌万千~~😎😎 文章目录 写在前面一、栈1.1栈的概念及结构1.2、栈的实现1.2.1、栈的结构体定义1.2.2、栈的初始化栈1.2.3、入栈1.2.4、出栈…

A030-基于Spring boot的公司资产网站设计与实现

🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹 赠送计算机毕业设计600…

企业生产环境-麒麟V10(ARM架构)操作系统部署kafka高可用集群

前言:Apache Kafka是一个分布式流处理平台,由LinkedIn开发并捐赠给Apache软件基金会。它主要用于构建实时数据流管道和流应用。Kafka具有高吞吐量、可扩展性和容错性的特点,适用于处理大量数据。 以下是Kafka的一些核心概念和特性&#xff1…

供应链管理、一件代发系统功能及源码分享 PHP+Mysql

随着电商行业的不断发展,传统的库存管理模式已经逐渐无法满足市场需求。越来越多的企业选择“一件代发”模式,即商家不需要自己储备商品库存,而是将订单直接转给供应商,由供应商直接进行发货。这种方式极大地降低了企业的运营成本…

机器学习 ---线性回归

目录 摘要: 一、简单线性回归与多元线性回归 1、简单线性回归 2、多元线性回归 3、残差 二、线性回归的正规方程解 1、线性回归训练流程 2、线性回归的正规方程解 (1)适用场景 (2)正规方程解的公式 三、衡量…

Unity类银河战士恶魔城学习总结(P127 Stat ToolTip属性提示)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了把鼠标放到属性上面就会显示属性的作用 UI_StatToolTip.cs 这段代码实现了一个UI提示框(ToolTip)功能…

C/C++语言基础--initializer_list表达式、tuple元组、pair对组简介

本专栏目的 更新C/C的基础语法,包括C的一些新特性 前言 initializer_list表达式、tuple元组、pair对组再C日常还是比较常用的,尤其是对组在刷算法还是挺好用的,这里做一个简介;这三个语法结合C17的结构化绑定会更好用&#xff…

Python_爬虫1_Requests库入门

目录 Requests库 7个主要方法 Requests库的get()方法 Response对象的属性 爬取网页的通用代码框架 理解requests库的异常 HTTP协议及Requests库方法 HTTP协议 HTTP协议采用URL作为定位网络资源的标识。 HTTP协议对资源的操作 理解PATCH和PUT的区别 HTTP协议与Requse…

视频流媒体播放器EasyPlayer.js RTSP播放器视频颜色变灰色/渲染发绿的原因分析

EasyPlayer.js RTSP播放器属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,无须安装任何插件,起播快、延迟低、兼容性强,使用非常便捷。 EasyPlayer.js播放器不仅支持H.264与H.265视频编码格式&#xff0…

[JAVA]有关MyBatis环境配置介绍

什么是MyBatis环境配置? MyBatis是基于JDBC对数据库进行操作,在我们进行数据操作时,我们需要告诉MyBatis我们连接哪个数据库,ip地址,数据库名称,用户名密码等。以此来进行环境配置。 首先,MyB…

微搭低代码入门05循环

目录 1 for 循环2 while 循环3 do...while 循环4 break 语句5 循环展示组件总结 在编程中,循环是一种非常强大的控制结构,它允许我们重复执行一段代码直到满足某个条件为止。在微搭中,我们一般用循环来处理我们数据库返回的结果。 在微搭中&a…

11.13机器学习_线性回归

十 集成学习方法之随机森林 机器学习中有一种大类叫集成学习(Ensemble Learning),集成学习的基本思想就是将多个分类器组合,从而实现一个预测效果更好的集成分类器。集成算法可以说从一方面验证了中国的一句老话:三个…

活动|华院计算作为联盟理事单位出席进博会全球人工智能合作论坛

第七届中国国际进口博览会(进博会)于11月5日至10日在上海举行,作为本次进博会的重要配套活动,首届人工智能全球合作论坛也于9日圆满落幕。本次论坛由全球招商中心委员会、人工智能全球合作论坛组委会主办,中国国际科技…

2、开发工具和环境搭建

万丈高楼平地起,学习C语言先从安装个软件工具开始吧。 1、C语言软件工具有两个作用 1、编辑器 -- 写代码的工具 2、编译器 -- 将代码翻译成机器代码0和1 接下来我们介绍两种C语言代码工具:devcpp 和 VS2019,大家可以根据自己的喜好安装。 dev…

【Qt实现虚拟键盘】

Qt实现虚拟键盘 🌟项目分析🌟实现方式🌟开发流程 🌟项目分析 需求:为Linux环境下提供可便捷使用的虚拟键盘OS环境:Windows 7/11、CentOS 7开发语言:Qt/C IDE:QtCreator 、Qt5.14.2功…

领夹麦克风哪个品牌好,手机领夹麦克风哪个牌子好,选购推荐

​无线麦克风凭借其无与伦比的便携性与灵活性,成为在演讲、表演以及会议等多种场合中不可或缺的有力帮手。它挣脱了线缆的束缚,使得声音的传播更加自由自在。其操作十分简便,只需简单配对就能投入使用,从而可以轻松地适应各类场景…

ADC输出码和输入电压转换关系

ADC输出码和输入电压转换关系 转换公式:ADC输出码(Vin / Vref) *2n 。其中Vin 是输入ADC芯片的电压,Vref是参考电压,n是ADC芯片的位数。 举个例子MS5182是一个16bit的ADC(21665536),参考电压Vref4.096V&a…

IROS讲座:如何写出受欢迎的论文

讲座原名称:How to write papers people love reading 时间地点:2024年10月中旬,阿布扎比国家展览中心,阿联酋 演讲嘉宾照片: 以下是拍摄的部分PPT,并添加了中文笔记:

【Docker】Mac安装Docker Desktop导致磁盘剩余空间较少问题如何解决?

目录 一、背景描述 二、解决办法 三、清理效果 四、理论参考 解决方法 1. 清理未使用的 Docker 镜像、容器和卷 2. 查看 Docker 使用的磁盘空间 3. 调整 Docker 的存储位置 4. 增加磁盘空间 5. 调整 Docker Desktop 配置 6. 使用 Docker 清理工具(例如 D…

Tiktok对接和内容发布申请流程

这段时间在搞AI生成视频,希望用户能一键发布到Tiktok,因此研究了一下Tiktok的开发者申请流程,发现好复杂,同时也发现Tiktok的开发也跟我一样,挺草台班子的 0、流程简述 废话不多说,Tiktok的开发者申请和…