【JavaEE】线程安全的集合类
文章目录
- 前言
- 多线程环境使用 ArrayList
- 多线程环境使用队列
- 多线程环境使用哈希表
- 1. HashTable
- 2. ConcurrentHashMap
前言
前面我们学习了很多的Java集合类,像什么ArrayList、Queue、HashTable、HashMap等等一些常用的集合类,之前使用这些都是在单线程中使用的,而如今我们学习了多线程之后就要考虑这些集合在多线程中使用是否会发生一些线程不安全的问题。
原来的集合类大部分都是线程不安全的,除了Vector、Stack、HashTable,是线程安全的(但是这些都不建议使用了,因为Java官方已经将这些集合类标记了,随时都有可能被删除),其他的集合类就是线程不安全的。
多线程环境使用 ArrayList
因为 ArrayList 在多线程环境下可能涉及到同时读和写的操作从而导致线程不安全。为了解决在使用 ArrayList 线程不安全的问题,有以下几种解决方法。
- 自己使用同步机制(使用 synchronized 或者 ReentrantLock 加锁等)
- Collections.synchronizedList(new ArrayList); 使用这个集合类就是在相关方法前面进行 synchronized 加锁
synchronizedList 是标准库提供的一个基于 synchronized 进行线程同步的 List.
synchronizedList 的关键操作上都带有 synchronized
- 使用 CopyOnWriteArrayList
CopyOnWriteArrayList 即写时复制容器,当进行写操作的时候,不是直接添加进容器中,而是先Copy复制出一个容器,将新元素添加进新容器中。当添加完成之后就将原容器的引用指向新容器。这样就可以保证在写的时候,不需要进行加锁,也可以读,并且读的数据是正确的。
CopyOnWriteArrayList 容器的优缺点:
优点:
- 线程安全:CopyOnWriteArrayList 是线程安全的,你可以在多线程环境中无需额外的同步或锁定就能使用它。
- 读操作无需锁定:由于它使用了写时复制策略,所以读取操作(例如 get 和 iterator)可以在没有锁定的情况下进行,这使得它非常适合读多写少的场景。
- 避免阻塞:CopyOnWriteArrayList 使用了一种称为 “乐观锁” 的策略,这意味着它不会在执行修改操作时阻塞读取操作。
缺点:
- 写操作开销大:每次修改操作都会复制整个底层数组,这在数组较大时可能会导致显著的性能开销。因此,CopyOnWriteArrayList 不适合写操作频繁的场景。
- 内存消耗大:由于每次写操作都会复制整个数组,这可能会导致大量的内存消耗。
- 迭代器一致性:CopyOnWriteArrayList 的迭代器是弱一致性的(weakly consistent)。这意味着如果你在迭代过程中修改了列表(除非是通过迭代器自己的 remove 方法),那么迭代器可能不会反映这些修改。
总的来说,CopyOnWriteArrayList 是一种非常有用的工具,但是你应该清楚它的适用场景:读多写少,且数据大小适中。如果你在一个写操作频繁或者数据非常大的场景中使用它,可能会遇到性能问题。
多线程环境使用队列
因为队列先进先出的特性,所以主要的线程安全问题就是当队列为空的时候读取和队列为满的时候插入,为了解决队列在多线程中会出现的问题,主要就是使用了阻塞队列的方法使队列为空时读取数据和队列为满时的插入数据操作进入阻塞等待状态。
- ArrayBlockingQueue
基于数组实现的阻塞队列 - LinkedBlockingQueue
基于链表实现的阻塞队列 - PriorityBlockingQueue
基于堆实现的带优先级的阻塞队列 - TransferQueue
最多只包含一个元素的阻塞队列
多线程环境使用哈希表
在多线程环境下使用哈希表可以使用:
- HashTable
- ConcurrentHashMap
1. HashTable
HashTable 只是给一些关键方法加上了 synchronized 锁,是直接加在方法上的,也就相当于给 HashTable 对象加锁。
对整个对象加锁就意味着:
- 如果多线程访问同一个 Hashtable 就会直接造成锁冲突.
- size 属性也是通过 synchronized 来控制同步, 也是比较慢的.
- 一旦触发扩容, 就由该线程完成整个扩容过程. 这个过程会涉及到大量的元素拷贝, 效率会非常低.
但是实际上,并不是多个线程只要访问同一个 HashTable 对象需要进行加锁,而是只有当两个线程访问到同一个链表的时候才需要进行加锁,并且哈希寻址的时候两个线程同时找到同一个链表的几率是比较小的,所以没必要将整个哈希表都进行加锁。
2. ConcurrentHashMap
ConcurrentHashMap 在 HashTable 的基础上做出了一系列的优化。
- ConcurrentHashMap 将 HashTable 的一个大锁转换为了一个一个加在锁桶的小锁,大大降低了锁冲突的现象。
- 充分利用 CAS 特性,避免了一些不必要加锁的情况。比如更改哈希表中的元素个数 size 时候就使用 CAS 原子操作,不进行加锁。
- ConcurrentHashMap 对读操作没有进行加锁,也就是说当多个线程同时进行读和读操作、读和写操作的时候都不会出现锁竞争的现象。
但是如果不对读操作进行加锁的话,会不会发生读到了一个只修改了一半的数据呢?
答:
其实是不会的,因为 ConcurrentHashMap 在底层编码的时候,比较谨慎的处理了一些细节。在修改操作的时候会避免使用++和- -的这些非原子性的操作,而是使用 = 这种原子性的操作。有了这些操作,就使得读取到的数据要么是修改之前的数据,要么是修改值时候的数据,不会出现读取到的数据是只修改了一半的数据。
- 优化了扩容方式: 化整为零。通过这个优化就避免了短时间内因哈希表中元素过多进行扩容的时候,需要改变的元素过多而造成计算机需要承担的负担过重而导致阻塞的情况。
- 发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去.
- 扩容期间, 新老数组同时存在.
- 后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素.
- 搬完最后一个元素再把老数组删掉.
- 这个期间, 插入只往新数组加.
- 这个期间, 查找需要同时查新数组和老数组
相关文章:
【JavaEE】线程安全的集合类
文章目录 前言多线程环境使用 ArrayList多线程环境使用队列多线程环境使用哈希表1. HashTable2. ConcurrentHashMap 前言 前面我们学习了很多的Java集合类,像什么ArrayList、Queue、HashTable、HashMap等等一些常用的集合类,之前使用这些都是在单线程中…...
【C++算法】is_partitioned、partition_copy和partition_point
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、is_partitioned函数:1.1 is_partitioned是什么?1.2 函数原型1.3 示例代码1.4 更多示例代码 二、partition_copy函数2.1 概念2.2 函数…...
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查…...
『力扣每日一题15』:买卖股票的最佳时机
一、题目 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的…...
Java中栈实现怎么选?Stack、Deque、ArrayDeque、LinkedList(含常用Api积累)
目录 Java中的Stack类 不用Stack有以下两点原因 1、从性能上来说应该使用Deque代替Stack。 2、Stack从Vector继承是个历史遗留问题,JDK官方已建议优先使用Deque的实现类来代替Stack。 该用ArrayDeque还是LinkedList? ArrayDeque与LinkList区别࿱…...
雷达分辨率单元、单向/双向雷达方程、天气雷达方程简介
一、点状目标 如果两个点状目标在一个分辨率单元中,经典脉冲雷达只能看到一个目标。 点状目标 二、雷达距离分辨率 对于简单的键控开/关脉冲调制: 对于使用脉冲内调制的雷达,距离分辨率取决于压缩脉冲的脉冲持续时间。脉冲压缩比(PCR)取决于传输带宽BWtx,即距离分辨率取…...
RabbitMQ之Fanout(扇形) Exchange解读
目录 基本介绍 适用场景 springboot代码演示 演示架构 工程概述 RabbitConfig配置类:创建队列及交换机并进行绑定 MessageService业务类:发送消息及接收消息 主启动类RabbitMq01Application:实现ApplicationRunner接口 基本介绍 Fa…...
Redisson—分布式集合详述
7.1. 映射(Map) 基于Redis的Redisson的分布式映射结构的RMap Java对象实现了java.util.concurrent.ConcurrentMap接口和java.util.Map接口。与HashMap不同的是,RMap保持了元素的插入顺序。该对象的最大容量受Redis限制,最大元素数…...
开发做前端好还是后端好?这是个问题!
前言 随着互联网的快速发展,越来越多的人选择从事Web开发行业,而Web开发涉及到前端和后端两个方面,相信许多人都曾经对这两个方面进行过探究。而且编程世界就像一座大城市,前端开发和后端开发就像城市的两个不同街区。作为初学者&…...
运行huggingface Kosmos2报错 nameerror: name ‘kosmos2tokenizer‘ is not defined
尝试运行huggingface上的Kosmos,https://huggingface.co/ydshieh/kosmos-2-patch14-224失败,报错: nameerror: name kosmos2tokenizer is not defined查看报错代码: vi /root/.cache/huggingface/modules/transformers_modules/ydshieh/kosmos-2-patch14-224/48e3edebaeb…...
吃鸡玩家必备神器!一站式提升战斗力、分享干货!
大家好,我是吃鸡玩家。在这个视频中,我要分享一个让你瞬间提高战斗力的神器,同时让你享受到顶级游戏作战干货的盛宴!让我们一起来了解吧! 首先,我们推荐绝地求生作图工具。通过这款工具,你可以轻…...
【maven】idea中基于maven-webapp骨架创建的web.xml问题
IDEA中基于maven-webapp骨架创建的web工程,默认的web.xml是这样的。 <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name…...
【算法题】2034. 股票价格波动
插: 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 坚持不懈,越努力越幸运,大家一起学习鸭~~~ 题目: 给你一支股票价格的数据流。数据流…...
APSIM模型】作物模型应用案例
APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生长模拟模型之一。APSIM模型有Classic和Next Generation两个系列模型,能模拟几十种农作物、牧草和树木的土壤-植物-大气过程,被广泛应用于精细农业、水肥管理、气候变化、粮食安…...
io_uring之liburing库安装
手动编译和安装 liburing: 1.首先,从 liburing 的 GitHub 仓库中获取源代码。您可以使用以下命令克隆仓库: git clone https://github.com/axboe/liburing.git2.进入 liburing 目录: cd liburing3.运行configure ./configure …...
Python WebSocket自动化测试:构建高效接口测试框架!
为了更高效地进行WebSocket接口的自动化测试,我们可以搭建一个专门的测试框架。本文将介绍如何使用Python构建一个高效的WebSocket接口测试框架,并重点关注以下四个方面的内容:运行测试文件封装、报告和日志的封装、数据驱动测试以及测试用例…...
MySQL数据库——SQL优化(1)-介绍、插入数据、主键优化
目录 介绍 插入数据 Insert 大批量插入数据 主键优化 数据组织方式 页分裂 页合并 索引设计原则 介绍 SQL优化将分为下面几个部分进行学习: 插入数据主键优化order by优化group by优化limit优化count优化update优化 首先就先来看第一方面, 插…...
Flink---10、处理函数(基本处理函数、按键分区处理函数、窗口处理函数、应用案例TopN、侧输出流)
星光下的赶路人star的个人主页 我的敌手就是我自己,我要他美好到能使我满意的程度 文章目录 1、处理函数1.1 基本处理函数(ProcessFunction)1.1.1 处理函数的功能和使用1.1.2 ProcessFunction解析1.1.3 处理函数的分类 1.2 按键分区处理函数&…...
多种方案教你彻底解决mac npm install -g后仍然不行怎么办sudo: xxx: command not found
问题概述 某些时候我们成功执行了npm install -g xxx,但是执行完成以后,使用我们全局新安装的包依然不行,如何解决呢? 解决方案1: step1: 查看npm 全局文件安装地址 XXXCN_CXXXMD6M ~ % npm list -g …...
斐波那契数列 JS
问题: 给出一个数字,找出它是斐波那契数列中的第几个数 斐波那契数列 [1, 1, 2, 3, 5, 8, 13, ...],后一个数字是前两个数字之和 输入的数字大于等于 2 如果输入数字不存于斐波那契数列中,返回 -1 function demo(num) {//初始数据…...
IP 地址的分类
IP地址是用于标识计算机或设备在互联网上的位置的一种地址。IP地址通常根据其范围和用途分为不同的分类,主要包括以下几种: IPv4地址(Internet Protocol version 4): IPv4地址是32位二进制数,通常以点分十…...
CDN网络基础入门:CDN原理及架构
背景 互联网业务的繁荣让各类门户网站、短视频、剧集观看、在线教育等内容生态快速发展,互联网流量呈现爆发式增长,自然也面临着海量内容分发效率上的挑战,那么作为终端用户,我们获取资源的体验是否有提升呢? 答案是…...
李沐深度学习记录2:10多层感知机
一.简要知识记录 x.numel():看向量或矩阵里元素个数 A.sum():向量或矩阵求和,axis参数可对某维度求和,keepdims参数设置是否保持维度不变 A.cumsum:axis参数设置沿某一维度计算矩阵累计和x*y:向量的按元素乘法 torch.…...
Python标准库中内置装饰器@staticmethod@classmethod
装饰器是Python中强大而灵活的功能,用于修改或增强函数或方法的行为。装饰器本质上是一个函数,它接受另一个函数作为参数,并返回一个新的函数,通常用于在不修改原始函数代码的情况下添加额外的功能或行为。这种技术称为元编程&…...
MySQL8 间隙锁在11种情况下的锁持有情况分析
测试环境及相关必要知识 测试环境为mysql 8 版本 间隙锁(Gap Lock):用于锁定索引范围之间的间隙,防止其他事务在此间隙中插入新记录。间隙锁主要用于防止幻读问题。 在可重复读的隔离级别下默认打开该锁机制,解决幻…...
C# 图片按比例进行压缩
1、对图片进行压缩,保存在本地 对于一个200k的png文件按0.6的缩放比例进行压缩,压缩后的大小为20k左右 对于一个80k的jpg文件按0.6的缩放比例压缩,压缩后为13k左右 public void imageZoom(string name, Double zoomScale){Bitmap btImage …...
猜猜 JavaScript 输出:(! + [] + [] + ![]).length
一起猜 最近看到一个很有意思的题,直接来看,下面这段代码的打印结果是什么? console.log((! [] [] ![]).length) 猜猜看,你的答案是什么,打在评论区。 我的答案是 undefined,正如我的英文名 为什么呢&a…...
MTK Android12静默安装接口
该文档就是在android12系统上提供一个广播接收器,app端发送一个广播,并且带入apk的地址就可以实现安装 1、广播注册 frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java 首先要导入的依赖 import android.app.P…...
基于电容电流前馈与电网电压全前馈的三相LCL并网逆变器谐波抑制Simulink仿真
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Python数据攻略-Pandas与统计数据分析
统计学在数据分析中到底有多重要?在数据分析的世界里,统计学扮演着一角色。想象一下你是《三国志》游戏的数据分析师,任务是找出哪个武将最受玩家欢迎,哪些战役最具挑战性等。 你怎么做呢?这就需要统计学的力量了。 文章目录 基础统计方法描述性统计方差和标准差相关性和…...
国学大师网站谁做的/网络公司网络推广服务
Im Shendi,之前使用到JavaFX,感觉... ....(使用 java 自带的 swing 和 awt 比较多 并且已经熟悉) 所以我找了找Eclipse有没有Java自带的swing或者awt的 可视化插件, 进行桌面开发当然是可视化开发更简单,效率更高. 使用Eclipse的WindowBuilder插件可以让我们进行可视化开发.…...
动态效果酷炫的网站/搜索引擎营销的英文缩写是
嗯,今天好不容易把鸽了好久的缩点给弄完了……感觉好像……很简单? 算法的目的,其实就是在有向图上,把一个强连通分量缩成一个点……然后我们再对此搞搞事情,\(over\) 哦对,时间复杂度很显然是\(\Theta(n)\…...
游戏网站app/石家庄网站建设方案推广
解决方法如下: 1>、进入超级用户模式。也就是输入"su -",系统会让你输入超级用户密码,输入密码后就进入了超级用户模式。 2>、添加文件的写权限。也就是输入命令"chmod uw /etc/sudoers"。 3>、编辑/etc/sudoers文件…...
济宁做网站的公司/种子搜索
前提: 1. 是否带表头 SQL> set heading on SQL> set heading off 2. 控制一行长度 SQL> set line 4000 HEADING和as用法一样,只是更简略。使用HEADING后,查询时列名不变,列标题变。 语法: column 列名1 format 列长 heading 列标题,类似as后面的类容; …...
做网站日ip100/软文推广文章范文1000
大家在使用电脑的时候,总是感觉不知道该用什么样的软件,或者找不到好用的软件。那么今天给大家分享6款电脑必备软件,能快速提高你的工作效率,每一个都十分良心。感兴趣的朋友,下面就跟着我一起来看看吧。一、7zip7zip这…...
网站分析模板/安卓优化大师官方版
暴力就好了 #include<bits/stdc.h> using namespace std; int a,b,c; int main(){cin>>a>>b>>c;for(int i1;;i){if(i%23a&&i%233b&&i%2333c){cout<<i;return 0;}} }...