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

news2024/11/20 6:13:56

文章目录

  • 🍀前言
  • 🌲多线程环境使用 ArrayList
    • 🚩自己使用同步机制 (synchronized 或者 ReentrantLock)
    • 🚩Collections.synchronizedList(new ArrayList);
    • 🚩使用 CopyOnWriteArrayList
  • 🎍多线程环境使用队列
  • 🎋多线程环境使用哈希表
    • 🚩Hashtable
    • 🚩ConcurrentHashMap
  • 🌳相关面试题
  • ⭕总结

🍀前言

原来的集合类, 大部分都不是线程安全的.

Vector, Stack, HashTable, 是线程安全的(不建议用), 其他的集合类不是线程安全的.

为什么不建议使用呢?

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

所以我们更多的是搭配一下其他方案达到线程安全,比如以下几种

🌲多线程环境使用 ArrayList

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

这里博主就不做过多赘述了,不懂得宝子可以去看一下博主对着方面的讲解

🚩Collections.synchronizedList(new ArrayList);

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

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

🚩使用 CopyOnWriteArrayList

使用CopyOnWrite容器即写时复制的容器

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

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

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

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

优点:

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

缺点:

  1. 占用内存较多.

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

🎍多线程环境使用队列

这个博主在讲【JavaEE初阶】 阻塞式队列详解中也有提到,所以这里只是简单列举

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

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

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

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

🎋多线程环境使用哈希表

HashMap 本身不是线程安全的.

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

  • Hashtable

  • ConcurrentHashMap

🚩Hashtable

Hashtable在实现过程中只是简单的把关键方法加上了 synchronized 关键字.
在这里插入图片描述
在这里插入图片描述

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

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

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

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

🚩ConcurrentHashMap

相比于 Hashtable 做出了一系列的改进和优化. 以 Java1.8 为例

  • 读操作没有加锁(但是使用了 volatile 保证从内存读取结果), 只对写操作进行加锁. 加锁的方式仍然是是用 synchronized, 但是不是锁整个对象, 而是 “锁桶” (用每个链表的头结点作为锁对象), 大大降低了锁冲突的概率.

  • 充分利用 CAS 特性. 比如 size 属性通过 CAS 来更新. 避免出现重量级锁的情况.

优化了扩容方式: 化整为零

  • 发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去.

  • 扩容期间, 新老数组同时存在.

  • 后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素.

  • 搬完最后一个元素再把老数组删掉.

  • 这个期间, 插入只往新数组加.

  • 这个期间, 查找需要同时查新数组和老数组
    在这里插入图片描述
    想要详细了解的读者可以去ConcurrentHashMap源码分析(JDK8版本)进行查看

🌳相关面试题

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

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

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

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

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

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

  1. Hashtable和HashMap、ConcurrentHashMap 之间的区别?
  • HashMap: 线程不安全. key 允许为 null

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

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

⭕总结

关于《【JavaEE初阶】 线程安全的集合类》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

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

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

相关文章

通过jdk自制https证书并配置到nginx并配置http2

生成证书 这里使用自己生成的免费证书。在${JAVA_HOME}/bin 下可以看到keytool.exe,在改目录打开cmd然后输入: keytool -genkey -v -alias lgq.com -keyalg RSA -keystore d:/zj/ssl/fastfly.com.keystore -validity 3650生成证书过程中:【你的名字】对…

美国海运专线冬季通航情况

随着全球经济一体化的推进,海运业务的重要性日益凸显。特别是在美国,作为世界上最大的经济体之一,其海运业务的发展对全球物流供应链有着重要影响。而在冬季,美国海运专线又会面临怎样的通航情况呢?下面就让我们一起来探讨一下。…

区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第二套区块链系统部署与运维

第二套区块链系统部署与运维题目 环境 : ubuntu20 fisco : 2.8.0 docker: 20.10.21 webase-deploy : 1.5.5 mysql: 8.0.34 子任务1-2-1: 搭建区块链系统并验证(4分) 使用build_chain.sh 脚本文件进行搭建区块链 ,要求: 四节点,默认配置,单机,docker root@192-168-19…

【推荐】如何使用drawio的编辑器,看本文就够

学会使用drawio的编辑器 drawio是免费的开源的图表应用,你可以通过app.diagrams.net使用在线版本或者下载离线安装版在桌面端使用。 对于团队来讲, 把数据存储作为安全第一的图表应用, 你可以选择存储数据到不同的介质。例如Atlassian Conf…

deepxde更改backend

deepxde更改backend 1. 问题描述2. 解决方案 1. 问题描述 如果在使用deepxde库时,想使用除tensorflow.compat.v1之外的后端依赖,例如pytorch,会出现如下情况: 这时提示目前的后端依赖是tensorflow.compat.v1,需要更改…

RHCE---正则表达式

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 一. 文本搜索工具 grep是linux中一种强大的文件搜索过滤工具,可以按照正 则表达式检索文件内容,并把匹配的结果显示到屏幕上 (匹配的内容会标红&#x…

[Python]Selenium-自动化测试

Selenium是一个web自动化测试的工具,在使用之前先在对应的项目添加工具包噢. 本文章主要简单的介绍了selenium对于自动化测试的使用 目录 添加浏览器驱动 get函数来到对应网站 驱动的定位 元素定位 id定位 class name定位 CSS定位 XPath定位 link text定位 定位一…

【如何去掉Unity点击运行时,Photon的警告弹窗】

如何去掉Unity点击运行时,Photon的警告弹窗 一、前言二、解决办法1、解决思路2、解决步骤 一、前言 我导入了Photon插件,但是我现在用不着,又不想将其删掉,Photon的配置也没有弄,导致现在一运行Unity,就会…

python re 使用非捕获组来忽略第一个value的匹配结果

import retext " value1,value2,value3 "pattern r"(?:value\d,){2}value(\d)"match re.search(pattern, text) print(match.group(1)) 其中,(?:...)表示非捕获组,{1}表示匹配前面的模式一次。该正则表达式的含义是&#xff1a…

力扣刷题 day56:10-26

1.解码异或后的数组 未知 整数数组 arr 由 n 个非负整数组成。 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encoded[i] arr[i] XOR arr[i 1] 。例如,arr [1,0,2,1] 经编码后得到 encoded [1,2,3] 。 给你编码后的数组 encoded 和原…

Hbase基本使用,读写原理,性能优化学习

文章目录 HBase简介HBase定义HBase数据模型**HBase** **逻辑结构****HBase** **物理存储结构****HBase** **基本架构** HBase 入门**HBase** **安装部署****HBase** 配置文件**HBase** 启动停止**HBase** **访问页面****HBase** **高可用****HBase Shell****HBase API**HBaseCo…

解决msvcp120.dll丢失的问题的5个方法,修复系统dll问题

在使用计算机的过程中,我们经常会遇到各种各样的动态链接库(DLL)文件。其中之一就是“msvcp120.dll丢失”。这个错误通常会导致某些应用程序无法正常运行。为了解决这个问题,我们需要找到合适的方法来修复丢失的msvcp120.dll文件。…

用Wireshark在本机环回接口上抓包

Wireshark版本下载、安装 访问官网:https://www.wireshark.org/ 可以下载最新的版本,例如4.0.10版本。包比较大,可能下载得比较慢。 下载到本地后,双击按照提示安装就行了。 在环回接口上抓包 启动Wireshark,双击在…

【网络】想学TCP,这一篇就够了 —— TCP理论知识详解(基于前面手搓TCP服务端博客的补充)

TCP理论 前言正式开始TCP报文如何进行分离和封装TCP如何将有效载荷交付给上层如何理解TCP的可靠性TCP报头中的序号和确认序号(简单过一下,后面还会详细讲)只要序号不要确认序号行不行乱序问题 16位窗口大小TCP的全双工通信方式16位窗口大小的…

java小程序商城免费搭建 VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城

涉及平台 平台管理、商家端(PC端、手机端)、买家平台(H5/公众号、小程序、APP端(IOS/Android)、微服务平台(业务服务) 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis …

C语言每日一题(20)最大公因数等于 K 的子数组数目

力扣 2447 最大公因数等于 K 的子数组数目 题目描述 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 nums 的子数组中元素的最大公因数等于 k 的子数组数目。 子数组 是数组中一个连续的非空序列。 数组的最大公因数 是能整除数组中所有元素的最大整数。 …

【EI会议征稿】2024年电力电子与人工智能国际学术会议(PEAI 2024)

2024年电力电子与人工智能国际学术会议(PEAI 2024) 2024 International Conference on Power Electronics and Artificial Intelligence(PEAI 2024) 2024年电力电子与人工智能国际学术会议(PEAI 2024)将于…

C++基础算法⑦——信奥一本通递归算法(放苹果、求最大公约数问题、2的幂次方表示、分数求和、因子分解、判断元素是否存在)

递归算法 1206:放苹果1207:求最大公约数问题1208:2的幂次方表示1209:分数求和1210:因子分解1211:判断元素是否存在 1206:放苹果 这道题还是有些难度的,我们要考虑几种放苹果的情况。…

进程优先级、切换、调度

进程的特性是动态,并发,独立,异步,我们今天来浅显的从并发入手介绍各种知识 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。 为了高效完成任务,更合理…

利用Excel支持JUnit参数化测试

在JUnit里面,可以使用CsvFileSource读取csv文件进行参数化测试,可是CSV文件不支持格式,编辑颇为麻烦,尤其是多次编辑,因此自然想到是否可以使用Excel文件,可以有各种格式,支持各类数据。 最新开…