【JavaEE初阶】线程安全的集合类

news2024/9/24 5:33:00

📕 引言

我们之前讲过的集合类,,大部分都不是线程安全的.

Vector, Stack, HashTable, 是线程安全的(都是自带了synchronized,不建议用), 其他的集合类不是线程安全的。

注意:加锁不能保证线程一定安全,不加锁也不能确定线程一定不安全,具体代码具体分析

为什么不建议使用呢?

因为我们在使用的时候,这些类就会自动的加锁,虽然编译器会自动优化为没有锁竞争的线程进行锁消除的优化,但是呢万一编译器没有优化好,就麻烦了

如果需要用到其他的类,就需要手动加锁,来保证线程安全(不同情况加锁方式也不同)

🌲多线程环境使用 ArrayList

🚩自己使用同步机制 (synchronized 或者 ReentrantLock)

这里就不在过多讲述了

🚩Collections.synchronizedList(new ArrayList);

  • synchronizedList 是标准库提供的一个基于 synchronized 进行线程同步的List.

  • synchronizedList 的关键操作上都带有 synchronized

相当于给ArrayList这些集合类,套一层壳,壳上是给关键方法都加了synchronized

🚩使用 CopyOnWriteArrayList

也是一种解决线程安全的问题的做法

使用CopyOnWrite容器即"写时拷贝"的容器

  • 当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,

  • 添加完元素之后,再将原容器的引用指向新的容器

例子:

这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。

所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

优点:

  1. 在读多写少的场景下, 性能很高, 不需要加锁竞争.

缺点:

  1. 占用内存较多.

  2. 新写的数据不能被第一时间读取到

🎍多线程环境使用队列

这里简单讨论一下即可,前面讨论过。

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

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

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

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

🎋多线程环境使用哈希表

HashMap 本身不是线程安全的.

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

  • Hashtable(自带锁,只是线程比较安全,但不推荐使用)

  • ConcurrentHashMap(多线程使用哈希表,优先考虑这个)

🚩Hashtable

Hashtable在实现过程中只是简单的把关键方法加上了 synchronized 关键字.

观察源码即可:(就不一一展示了)

这相当于直接针对 Hashtable 对象本身加锁.

  • 如果多线程访问同一个 Hashtable 就会直接造成锁冲突.

  • size 属性也是通过 synchronized 来控制同步, 也是比较慢的.

  • 一旦触发扩容, 就由该线程完成整个扩容过程. 这个过程会涉及到大量的元素拷贝, 效率会非常低

🚩ConcurrentHashMap

相比于 Hashtable 做出了一系列的改进和优化. 

1.使用"锁桶"的方式,来代替"一把全局锁",有效的降低锁冲突的概率

2.HashMap的size,即使你插入的的元素是不同的链表上的元素,也会涉及到多个线程针对同一size变量进行修改。

引入 CAS ,通过 CAS 的方式来修改size,也就避免了加锁操作。也可进一步的提升效率

3.针对扩容操作的优化

核心思路:"化整为零"

注意:

ConcurrentHashMap 是一个工作中非常常用,面试非常高频的问题!!!整个多线程进行部分,哪怕别的不记得,这个一定记得。

细节:

🌳相关面试题

1.ConcurrentHashMap的读是否要加锁,为什么?

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

2.介绍下 ConcurrentHashMap的锁分段技术?

这个是 Java1.7 中采取的技术. Java1.8 中已经不再使用了. 简单的说就是把若干个哈希桶分成一个 “段” (Segment),针对每个段分别加锁. 目的也是为了降低锁竞争的概率. 当两个线程访问的数据恰好在同一个段上的时候, 才触发锁竞争.

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

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

4.Hashtable和HashMap、ConcurrentHashMap 之间的区别?

  • HashMap: 线程不安全. key 允许为 null
  • Hashtable: 线程安全. 使用 synchronized 锁,Hashtable 对象, 效率较低. key 不允许为 null.
  • ConcurrentHashMap: 线程安全. 使用synchronized 锁每个链表头结点, 锁冲突概率低, 充分利用 CAS 机制. 优化了扩容方式. key 不允许为 null

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

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

相关文章

spark-python

前言:本帖子是看了黑马教学视频结合spark八股,记录一下spark的知识. 一.spark介绍 1.1 spark的运行模式 1.2 spark的架构角色 在讨论spark的架构角色时,首先先回顾一下yarn的架构角色. spark架构角色: 二.standalone 运行原理 2.1standalone架构 standalone中有三类进程: m…

AI称重收银一体秤

系统介绍 专门为零售行业的连锁店量身打造的收银系统,适用于常规超市、生鲜超市、水果店、便利店、零食专卖店、服装店、母婴用品、农贸市场等类型的门店使用。同时线上线下数据打通,线下收银的数据与小程序私域商城中的数据完全同步,如商品…

如何在 Windows 11/10/8/7 中恢复已删除和未保存的记事本文本文件

很多原因都会导致未保存的记事本文本文件丢失。这些包括意外关闭、系统崩溃或电源故障等。无论丢失文本文件的原因是什么,相关的焦虑都是一样的。如果您遇到这种情况,可以使用以下有效方法在 Windows 11/10/8/7 中恢复已删除的文本文件。在这篇文章中&am…

NFT Insider #142:Mocaverse 在 The Sandbox 中推出 Mocaland 体验,Azuki 推出新系列动画片

NFT Insider 浓缩每周 NFT 新闻,为大家带来关于 NFT 最全面、最新鲜、最有价值的讯息。每期周报将从 NFT 市场数据,艺术新闻类,游戏新闻类,虚拟世界类,其他动态类,五个角度剖析 NFT 市场现状,了…

从新手到专家:2024年四大电脑录屏软件满足不同需求

电脑录屏是我们记录和分享信息的重要方式。无论是专业领域的技术演示,还是个人爱好的展示,一个好的录屏工具都能让我们的表达更加生动和直观。下面,就让我们一起探索几款市面上备受好评的电脑录屏软件。 福昕REC 链接:www.foxit…

金九银十,全网最详细的软件测试面试题总结

前面看到了一些面试题,总感觉会用得到,但是看一遍又记不住,所以我把面试题都整合在一起,都是来自各路大佬的分享,为了方便以后自己需要的时候刷一刷,不用再到处找题,今天把自己整理的这些面试题…

A股继续震荡盘整,无力回天还是蓄势待发?

今日A股走势十分反常,恐有大事将要发生了,直奔主题,马上告诉给所有人! 1、今天A股走势反常,昨夜外围纳指上涨2.87%,中概股也大涨了。今天亚太股市也在拉升,而A股却冲高回落,再度翻绿…

牛客JS题(二十八)控制动画

注释很详细&#xff0c;直接上代码 涉及知识点&#xff1a; css动态效果前提判断类型判断 题干&#xff1a; 我的答案 <!DOCTYPE html> <html><head><meta charset"utf-8" /><style type"text/css">#rect {width: 100px;he…

面试题(六)

1、等于操作符 “ ” 和全等操作符 “ ” 区别 有类型隐式转换&#xff0c;会先进行类型转换&#xff0c;再确定操作数是否相等&#xff08;若类型比较&#xff09;。 null undefined 结果为 true 没有类型隐式转换&#xff0c;只有两个操作数在不转换的前提下相等&#xff…

如何在 Android 手机/平板电脑上恢复误删除的 DCIM 文件夹

DCIM 文件夹是智能手机和平板电脑上最重要的文件夹之一。许多人报告说他们在 Android 设备上遇到了 DCIM 文件夹为空的问题。实际上&#xff0c;这种情况大多数情况下都会发生&#xff0c;当您意外从 Android 设备中删除 DCIM 文件夹或因病毒攻击、应用程序问题和意外格式化等原…

Android系统安全 — 6.5 Bluetooth安全连接原理

1 蓝牙协议架构和简称 蓝牙协议栈主要分&#xff1a;APPS层&#xff08;应用层&#xff0c;包括音频播放器&#xff0c;蓝牙遥控&#xff0c;智能家居APP等&#xff09;&#xff0c; HOST层&#xff08;中间层协议&#xff0c;包括GAP,SMP,ATT/GATT, L2CAP, AMP Manager&#x…

6自由度机械手DH坐标系建立

一、建立机械臂DH坐标系 Z为转动关节的转轴&#xff0c;Xi垂直于关节轴i和i1所在的平面&#xff0c;则根据上述方法可以建立坐标系如下图&#xff1a; 二、DH参数表 DH参数设定&#xff1a;机器人的每个连杆可以用4个运动学参数表示&#xff0c;DH法建立坐标系&#xff0c;xi-…

『状态模式』

首先创建一个项目 打开项目后复制至3个场景 命名为 创建一个空物体 命名为GameLoop 创建一个脚本GameLoop.cs 编写代码如下 将代码挂载至空物体GameLoop 将三个场景拖拽至Scenes In Build 分析下状态模式的类图 我们创新类图中的代码 编写ISceneState.cs 编写三个状态子类继承构…

Rust学习----Rust安装

如何安装Rust&#xff1f; 1.官网&#xff1a;https://www.rust-lang.org/zh-CN/ 2.Linux or Max: curl https://sh.rustup.rs -sSf | sh 3.Windows按官网指导安装。 4.Windows Subsystem for Linux&#xff1a; curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs…

2024年软件测试八股文(含答案+文档)

1、你的测试职业发展是什么&#xff1f; 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自己&…

Redis 数据结构深度解析

在浩瀚的数据存储海洋中&#xff0c;Redis以其卓越的性能和丰富的数据结构脱颖而出&#xff0c;成为众多开发者心中的瑰宝。作为一个高性能的键值存储系统&#xff0c;Redis不仅支持基础的字符串类型&#xff0c;还提供了哈希、列表、集合、有序集合等复杂数据结构&#xff0c;…

Git详细命令大全

一、创建版本库 创建目录&#xff1a;mkdir zzz 目录路径 进入目录&#xff1a;cd zzz 目录路径 查看当前目录路径&#xff1a;pwd 将当前目录变成Git仓库 &#xff1a;git init 二、代码存储 提交 添加文件到暂存区&#xff1a; 当前代码&#xff1a;git add . add与.之间有空…

医疗行业解决方案参考

医疗行业解决方案 互联网医院架构 患者门户&#xff1a;提供患者信息查询、挂号、缴费等基本服务。 预约挂号&#xff1a;允许患者在线预约挂号&#xff0c;减少现场排队等候时间。 挂号查询&#xff1a;患者可以查询挂号状态和相关信息。 院内导诊&#xff1a;提供院内导航…

2-60 基于matlab的时滞系统广义预测控制(GPC)算法仿真

基于matlab的时滞系统广义预测控制&#xff08;GPC&#xff09;算法仿真&#xff0c;不同控制加权矩阵控制效果对比&#xff0c;输入参数预测时域、控制时域、控制加权矩阵、误差加权矩阵。输出对比结果。程序已调通&#xff0c;可直接运行。 2-60 控制加权矩阵 误差加权矩阵 -…

Qgis 开发初级 《数据库和图层》

Qgis 可以加载很多数据源&#xff0c;像shapefile 文件&#xff0c; gdb文件等&#xff0c;还可以直接链接企业数据库。在这里&#xff0c;我只介绍比较常用的本地数据库 gdb。gdb 是esri 开发的数据库&#xff0c;gdb数据库不是开源的&#xff0c;qigs用了OpenFileGdb的驱动读…