【JavaEE】线程安全的集合类

在这里插入图片描述

文章目录

  • 前言
  • 多线程环境使用 ArrayList
  • 多线程环境使用队列
  • 多线程环境使用哈希表
    • 1. HashTable
    • 2. ConcurrentHashMap

前言

前面我们学习了很多的Java集合类,像什么ArrayList、Queue、HashTable、HashMap等等一些常用的集合类,之前使用这些都是在单线程中使用的,而如今我们学习了多线程之后就要考虑这些集合在多线程中使用是否会发生一些线程不安全的问题。

原来的集合类大部分都是线程不安全的,除了Vector、Stack、HashTable,是线程安全的(但是这些都不建议使用了,因为Java官方已经将这些集合类标记了,随时都有可能被删除),其他的集合类就是线程不安全的。

多线程环境使用 ArrayList

因为 ArrayList 在多线程环境下可能涉及到同时读和写的操作从而导致线程不安全。为了解决在使用 ArrayList 线程不安全的问题,有以下几种解决方法。

  1. 自己使用同步机制(使用 synchronized 或者 ReentrantLock 加锁等)
  2. Collections.synchronizedList(new ArrayList); 使用这个集合类就是在相关方法前面进行 synchronized 加锁

synchronizedList 是标准库提供的一个基于 synchronized 进行线程同步的 List.
synchronizedList 的关键操作上都带有 synchronized

  1. 使用 CopyOnWriteArrayList
    CopyOnWriteArrayList 即写时复制容器,当进行写操作的时候,不是直接添加进容器中,而是先Copy复制出一个容器,将新元素添加进新容器中。当添加完成之后就将原容器的引用指向新容器。这样就可以保证在写的时候,不需要进行加锁,也可以读,并且读的数据是正确的。

在这里插入图片描述

CopyOnWriteArrayList 容器的优缺点:

优点:

  • 线程安全:CopyOnWriteArrayList 是线程安全的,你可以在多线程环境中无需额外的同步或锁定就能使用它。
  • 读操作无需锁定:由于它使用了写时复制策略,所以读取操作(例如 get 和 iterator)可以在没有锁定的情况下进行,这使得它非常适合读多写少的场景。
  • 避免阻塞:CopyOnWriteArrayList 使用了一种称为 “乐观锁” 的策略,这意味着它不会在执行修改操作时阻塞读取操作。

缺点:

  • 写操作开销大:每次修改操作都会复制整个底层数组,这在数组较大时可能会导致显著的性能开销。因此,CopyOnWriteArrayList 不适合写操作频繁的场景。
  • 内存消耗大:由于每次写操作都会复制整个数组,这可能会导致大量的内存消耗。
  • 迭代器一致性:CopyOnWriteArrayList 的迭代器是弱一致性的(weakly consistent)。这意味着如果你在迭代过程中修改了列表(除非是通过迭代器自己的 remove 方法),那么迭代器可能不会反映这些修改。

总的来说,CopyOnWriteArrayList 是一种非常有用的工具,但是你应该清楚它的适用场景:读多写少,且数据大小适中。如果你在一个写操作频繁或者数据非常大的场景中使用它,可能会遇到性能问题。

多线程环境使用队列

因为队列先进先出的特性,所以主要的线程安全问题就是当队列为空的时候读取和队列为满的时候插入,为了解决队列在多线程中会出现的问题,主要就是使用了阻塞队列的方法使队列为空时读取数据和队列为满时的插入数据操作进入阻塞等待状态。

  1. ArrayBlockingQueue
    基于数组实现的阻塞队列
  2. LinkedBlockingQueue
    基于链表实现的阻塞队列
  3. PriorityBlockingQueue
    基于堆实现的带优先级的阻塞队列
  4. TransferQueue
    最多只包含一个元素的阻塞队列

多线程环境使用哈希表

在多线程环境下使用哈希表可以使用:

  1. HashTable
  2. ConcurrentHashMap

1. HashTable

HashTable 只是给一些关键方法加上了 synchronized 锁,是直接加在方法上的,也就相当于给 HashTable 对象加锁。

在这里插入图片描述
在这里插入图片描述

对整个对象加锁就意味着:

  • 如果多线程访问同一个 Hashtable 就会直接造成锁冲突.
  • size 属性也是通过 synchronized 来控制同步, 也是比较慢的.
  • 一旦触发扩容, 就由该线程完成整个扩容过程. 这个过程会涉及到大量的元素拷贝, 效率会非常低.

在这里插入图片描述
但是实际上,并不是多个线程只要访问同一个 HashTable 对象需要进行加锁,而是只有当两个线程访问到同一个链表的时候才需要进行加锁,并且哈希寻址的时候两个线程同时找到同一个链表的几率是比较小的,所以没必要将整个哈希表都进行加锁。

2. ConcurrentHashMap

ConcurrentHashMap 在 HashTable 的基础上做出了一系列的优化。

  1. ConcurrentHashMap 将 HashTable 的一个大锁转换为了一个一个加在锁桶的小锁,大大降低了锁冲突的现象。
    在这里插入图片描述
  2. 充分利用 CAS 特性,避免了一些不必要加锁的情况。比如更改哈希表中的元素个数 size 时候就使用 CAS 原子操作,不进行加锁。
  3. ConcurrentHashMap 对读操作没有进行加锁,也就是说当多个线程同时进行读和读操作、读和写操作的时候都不会出现锁竞争的现象。

但是如果不对读操作进行加锁的话,会不会发生读到了一个只修改了一半的数据呢?
答:
其实是不会的,因为 ConcurrentHashMap 在底层编码的时候,比较谨慎的处理了一些细节。在修改操作的时候会避免使用++和- -的这些非原子性的操作,而是使用 = 这种原子性的操作。有了这些操作,就使得读取到的数据要么是修改之前的数据,要么是修改值时候的数据,不会出现读取到的数据是只修改了一半的数据。

  1. 优化了扩容方式: 化整为零。通过这个优化就避免了短时间内因哈希表中元素过多进行扩容的时候,需要改变的元素过多而造成计算机需要承担的负担过重而导致阻塞的情况。
  • 发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去.
  • 扩容期间, 新老数组同时存在.
  • 后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素.
  • 搬完最后一个元素再把老数组删掉.
  • 这个期间, 插入只往新数组加.
  • 这个期间, 查找需要同时查新数组和老数组

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

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

相关文章

MyBatis(JavaEE进阶系列4)

目录 前言: 1.MyBatis是什么 2.为什么要学习MyBatis框架 3.MyBatis框架的搭建 3.1添加MyBatis框架 3.2设置MyBatis配置 4.根据MyBatis写法完成数据库的操作 5.MyBatis里面的增删改查操作 5.1插入语句 5.2修改语句 5.3delete语句 5.4查询语句 5.5like查…

IDEA 生成 javadoc

IDEA 生成 javadoc 在IDEA工具栏tools中,打开选项Generate JavaDoc(生成javaDoc 文件) 配置参数

什么是事件对象(event object)?如何使用它获取事件信息?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

【FISCO-BCOS】十六、多群组部署

目录 一、星形拓扑和并行多组 二、多群组部署(星形拓扑) 1、ipconf文件的编写 2、指定文件部署 3、检查节点共识 一、星形拓扑和并行多组 这是区块链应用中使用较广泛的两种组网方式 星形拓扑:中心机构节点同时属于多个群组,…

一、Excel VBA 是个啥?

Excel VBA 从入门到出门一、Excel VBA 是个啥?二、Excel VBA 简单使用 👋Excel VBA 是个啥? ⚽️1. Excel 中的 VBA 是什么?⚽️2. 为什么 VBA 很重要?⚽️3. 是否有无代码方法可以在 Excel 中实现工作流程自动化&…

深挖 Python 元组 pt.1

哈喽大家好,我是咸鱼 好久不见甚是想念,2023 年最后一次法定节假日已经结束了,不知道各位小伙伴是不是跟咸鱼一样今天就开始“搬砖”了呢? 我们知道元组(tuple)是 Python 的内置数据类型,tupl…

学信息系统项目管理师第4版系列20_风险管理

1. 针对不确定性的应对方法 1.1. 【高23上选58】 1.2. 收集信息 1.2.1. 可以对信息收集和分析工作进行规划,以便发现更多信息(如进行研究、争取专家参与或进行市场分析)来减少不确定性 1.3. 为多种结果做好准备 1.3.1. 制定可用的解决方…

手机投屏电脑软件AirServer5.6.3.0最新免费版本下载

随着智能手机的普及,越来越多的人喜欢用手机观看视频、玩游戏、办公等。但是,有时候手机屏幕太小,不够清晰,也不方便操作。这时候,如果能把手机屏幕投射到电脑上,就可以享受更大的视野,更流畅的…

nsoftware Cloud SMS 2022 .NET 22.0.8 Crack

nsoftware Cloud SMS 能够通过各种流行的消息服务(包括 Twilio、Sinch、SMSGlobal、SMS.to、Vonage、Clickatell 等)发送、接收和安排 SMS 消息,从而提供了一种简化且高效的消息服务方法。 Cloud SMS 提供单个 SMS 组件,允许通过…

微服务技术栈-Gateway服务网关

文章目录 前言一、为什么需要网关二、Spring Cloud Gateway三、断言工厂和过滤器1.断言工厂2.过滤器3.全局过滤器4.过滤器执行顺序 四、跨域问题总结 前言 在之前的文章中我们已经介绍了微服务技术中eureka、nacos、ribbon、Feign这几个组件,接下来将介绍另外一个组…

合成数据在计算机视觉任务中的应用指南

今年早些时候,我与 Cognizant 深度学习协会团队的一位经理进行了交谈。 他的团队使用深度学习算法创建概念验证(展示商业机会的试点项目)。 他注意到他的团队面临的主要挑战之一是获取此类 POC 的数据。 获取特定于某个问题的具有良好代表性的…

雷达波束高度估计、折射分类、大气波导现象概念

一、雷达波束高度估计 雷达波束在地球大气层中的传播并非直线,而是受到大气层的影响呈现出一种弯曲的形态,这种现象称为大气折射。这是由于地球大气的密度并非均匀,从地面到高空,大气的密度逐渐减小,因此电磁波在穿过大气层时,会因大气密度的变化而改变传播方向,形成弯曲…

2000至2022年中国月度植被覆盖度产品

简介: 中国区域2000至2022年月度植被覆盖度产品的空间分辨率250米,合成方式采用月最大值合成。本产品采用基于归一化植被指数(NDVI)像元二分模型,根据土地利用类型确定纯植被像元值和纯裸土像元值,计算中去…

cereal:支持C++11的开源序列化库

cereal:支持C11的开源序列化库 文章目录 一:引言二、cereal简介三、cereal的下载和使用 一:引言 序列化 (Serialization) 程序员在编写应用程序的时候往往需要将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的另…

互联网图片安全风控实战训练营开营!

内容安全风控,即针对互联网产生的海量内容的外部、内部风险做宏观到微观的引导和审核,从内容安全领域帮助企业化解监管风险和社会舆论风险,其核心是识别文本、图片、视频、音频中的有害内容。 由于互联网内容类型繁杂、多如牛毛,加…

JVM技术文档--JVM诊断调优工具Arthas--阿里巴巴开源工具--一文搞懂Arthas--快速上手--国庆开卷!!

​ Arthas首页 简介 | arthas Arthas官网文档 Arthas首页、文档和下载 - 开源 Java 诊断工具 - OSCHINA - 中文开源技术交流社区 阿丹: 之前聊过了一些关于JMV中的分区等等,但是有同学还是在后台问我,还有私信问我,学了这些…

三维模型3DTile格式轻量化的纹理压缩和质量关系分析

三维模型3DTile格式轻量化的纹理压缩和质量关系分析 在三维模型的3DTile格式轻量化处理中,纹理压缩是一个重要环节。但是,纹理压缩和模型质量之间存在明显的关系需要权衡。以下是纹理压缩和模型质量关系的详细分析: 1、压缩率与纹理质量&…

【UE】在游戏运行时,通过选择uasset来生成静态网格体

目录 主要流程 步骤 一、创建用于包含静态网格体的Actor蓝图 二、按钮点击事件 效果 主要流程 用户点击按钮后产生一个文件对话框,用户通过文件对话框选择指定的文件夹,我们获取到这个文件夹路径后处理成“按路径获取资产”节点所需的输入&#x…

【开发篇】二十、SpringBoot整合RocketMQ

文章目录 1、整合2、消息的生产3、消费4、发送异步消息5、补充:安装RocketMQ 1、整合 首先导入起步依赖,RocketMQ的starter不是Spring维护的,这一点从starter的命名可以看出来(不是spring-boot-starter-xxx,而是xxx-s…

【源码】hamcrest 源码阅读 空对象模式、模板方法模式的应用

文章目录 前言1. 类图概览2. 源码阅读2.1 抽象类 BaseMatcher2.1 接口 Description提炼模式:空对象模式 2. 接口 Description 与 SelfDescribing 配合使用提炼模式 模板方法 后记 前言 hamcrest ,一个被多个测试框架依赖的包。听说 hamcrest 的源码质量…