JavaEE 第16节 线程安全的集合类

news2024/11/25 18:49:30

目录

前言

顺序表

队列

哈希表

1、Hashtable

2、ConcurrentHashMap(重点)


前言

本文章主要介绍在多线程环境下如何线程安全的使用一些常用的集合类(顺序表和哈希表)。


顺序表

1、自己使用同步锁机制(synchornized和ReentrantLock)保证线程安全

2、Collections.synchronizedList()

它是 Java 中 java.util.Collections 类提供的一个基于synchronized关键字,给List加锁的静态方法,用于创建安全的List。

3、写时拷贝

Java中提供了CopyOnWrit这个容器来解决线程安全问题。

它的解决思路是:

在多个线程读取容器中的数据的时候不会做任何操作,但是当一个线程要修改容器中的数据的时候,不能立刻修改当前引用所指向的数据,而是重新拷贝一份相同的容器,在这个新的容器中去修改数据。在写入数据的时候,其他线程只能读取旧容器中的数据。等修改完毕,把引用现在已经修改好的新的容器(引用的赋值是一个原子操作)。

优点:

 在读多写少的环境下,因为没有加锁,所以没有锁开销,也没有锁竞争,性能高。

缺点:

  • 不能实现多个线程同时修改数据,因此不适用于写多读少的场景。
  • 因为拷贝的参与,所以当数据量本身很大的情况下会消耗内存,并且时间开销也会增大。

队列

关于队列的线程安全,自然使用到的是阻塞队列:

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

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

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

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

关于阻塞队列的详细介绍这里就不展开了,在同专栏第9节专门讲解了。


哈希表

HashMap本身是线程不安全的,在多线程环境下可以使用Hashtable/ConcurrentHashMap

1、Hashtable

Hashtable这个类只是对HashMap进行简单的加锁,也就是在关键方法上增加了synchronized关键字:

这就导致只要多个线程同时调用put或者get方法,即使他们想要访问的不是同一组数据,照样会进入阻塞状态,也就是所冲突,极大的影响了运行效率。

另外,如何在某一个线程使用put操作时,如果需要扩容,那么就会由当前线程进行扩容,如果涉及大量的元素拷贝,那么多线程的运行效率又会大幅降低。

总的来讲,HashTable相当于对整个哈希桶上了锁:

2、ConcurrentHashMap[推荐使用]

为了降低锁冲突概率,ConcurrentHashMap做出了以下优化:

  • 读操作:没有加锁,但是加了volatile保证内存可见。
  • 写操作:对每一个链表都进行了加锁(synchronized实现),如果写入数组中不同的下标,那么就不会发生所冲突,如图:
  • CAS的使用:在锁竞争并不激烈的情况下,采用CAS来更新size(键值对 增加/减少),这种方式不用加锁,更轻量,提高运行效率(jdk8引入)。
     
  • 分散计数器槽:在锁竞争激烈时,使用CAS就可能出现忙等的情况,使用CAS修改size就不太好了。为了避免多个线程同时修改同一个数据(size),ConcurrentHashMap引入了分散计数器槽(Counter Cells),它的原理如下:

  1、分散计数器槽的初始化:

.     ◦ 当多个线程进行插入或删除操作时,如果检测到对单个计数器的竞争变得激烈,ConcurrentHashMap会创建一个计数器槽数组。

      ◦ 这个数组中的每个槽(cell)都可以独立地更新,从而减少竞争。

  2、计数器槽的更新:

     ◦ 当一个线程需要更新size(例如插入或删除元素)时,它会尝试使用CAS操作更新某个计数器槽。

     ◦ 如果更新失败(因为另一个线程同时在更新这个槽),该线程会尝试更新另一个槽,直到成功为止。

  3、计数器槽的汇总:

     ◦ 当需要获取ConcurrentHashMap的大小时,size()方法会遍历所有计数器槽,将它们的值相加得到总的元素数量。


Counter Cells的核心思想就是使用数组来降低并发负载。

  • 扩容方式:与HashTable让发现需要扩容的线程去完成整个扩容任务不同,Concurrent把扩容任务分散给了多个线程去完成,即“化整为零”。
    大致步骤如下:​​​​

1、创建一个比原来还要大的数组。

2、每一个线程都尝试去获取一个没有完成旧数组到新数组迁移任务的桶(链表),然后对桶进行数据迁移、重新哈希(使用CAS保证线程安全,同时提高整体效率)。

3、所有桶都完成了数据迁移后,数组引用从旧数组指向新数组,扩容才真正完成。


注意,在扩容期间:

1)如果有put(插入操作),先对旧桶进行哈希,如果旧桶没有数据迁移,那么就插入到旧桶中,如果已经数据迁移,就插入到新桶中。

2)如果是get(查找操作),先找旧桶,旧桶没有找到,找新桶。

这种扩容方式大大提高了并发性能(逐步迁移,降低阻塞概率)以及系统稳定性(扩容时,单个线程锁占用时间不会激增)。


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

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

相关文章

模拟笔试:卡码网2023年快手笔试真题

1.158同余方程 思路 纯数学的思路&#xff0c;想不出来的话很难做。 欧几里得算法视频讲解 代码 #include <iostream> using namespace std;// 扩展欧几里得&#xff1a;计算 ax by gcd(a, b) 的解 long long extended_gcd(long long a, long long b, long long &a…

Java语言程序设计——篇十五(5)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f333;&#x1f333;&…

【STM32嵌入式系统设计与开发拓展】——16_FreeRTOS操作系统

参考&#xff1a;链接: 正点原子 一、认识裸机和RTOS 裸机是无操作系统支持&#xff0c;程序直接运行在硬件上&#xff0c;开发者要自行处理硬件细节。早期单片机常采用&#xff0c;优点是性能和资源利用率高&#xff0c;缺点是开发难、可移植性差。RTOS 是实时操作系统&…

vscode导入的包裹代码名称没有颜色

问题描述:代码其他染色正常,但是例如import torchtorch没有颜色,虽然能够识别(ctrl左键能够点进去看到torch代码) 解决: 下载extention pylancefile->preferences->settings, 搜索Python: Language Server, 从default改成pylance

JAVA—IO流

存储数据的方案File和文件数据的操作IO流&#xff0c;学习字节流和字符流&#xff0c;了解框架和IO框架Commons IO 目录 1.File &#xff08;1&#xff09;创建对象 &#xff08;2&#xff09;常用方法 【1】判断类型&#xff0c;获取信息 【2】创建文件&#xff0c;删除…

LNMP学习

一、LNMP—web 1. 概述 LNMP/LAMP linux/windows/unix apache/nginx mysql/pgsql php/jsp 2. nginx部署及其平滑升级 实操 3. nginx七层负载均衡及算法 算法参考文档&#xff1a;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/ 实操 4…

flv格式转换mp4怎么转换?5个软件帮助你自己快速进行格式转换

flv格式转换mp4怎么转换&#xff1f;5个软件让你从此快速转换格式不求别人 将FLV格式的视频转换为MP4格式可以通过使用以下五款软件来轻松实现。这些工具操作简便&#xff0c;能够快速高效地完成视频格式的转换&#xff0c;让你轻松应对各种视频格式需求。 口袋视频转换器 这…

网安新声 | 网易云音乐崩了:网络安全如何守护在线体验

网安加社区【网安新声】栏目&#xff0c;汇聚网络安全领域的权威专家与资深学者&#xff0c;紧跟当下热点安全事件、剖析前沿技术动态及政策导向&#xff0c;以专业视野和前瞻洞察&#xff0c;引领行业共同探讨并应对新挑战的策略与可行路径。 8月19日&#xff0c;#网易云音乐崩…

“休闲化“趋势增强,IAA手游出海如何抓住增长机遇?

进入存量时代&#xff0c;全球手游市场正面临严峻的挑战。数据显示&#xff0c;2023年 App Store 和 Google Play 的全球双端下载量同比下降10%&#xff0c;IAP 收入也同比减少2%。而作为大盘的支柱品类&#xff0c;中重度手游首当其冲。以 RPG 和 SLG 品类为例&#xff0c;虽然…

Halo个人博客Docker部署结合内网穿透为本地站点配置公网地址远程访问

文章目录 前言1. Docker部署Halo1.1 检查Docker版本如果未安装Docker可参考已安装Docker步骤&#xff1a;1.2 在Docker中部署Halo 2. Linux安装Cpolar2.1 打开服务器防火墙2.2 安装cpolar内网穿透 3. 配置Halo个人博客公网地址4. 固定Halo公网地址 前言 本文主要介绍如何在Cen…

常见计算机网络协议汇总(非常详细)从零基础入门到精通,看完这一篇就够了

文章目录 前言计算机网络五层模型回顾应用层协议 DNS协议&#xff1a;HTTP协议HTTPS协议 传输层协议 UDP协议TCP 网络层 IP协议ICMP协议 数据链路层 ARP协议 物理层整体的网络传输流程 1️⃣网络安全零基础入门 ① 学习路线② 路线对应学习视频 2️⃣视频配套资料&国内外网…

二分+前缀和+思维,CF 1902D - Robot Queries

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1902D - Robot Queries 二、解题报告 1、思路分析 不管怎么反转: 起点终…

【新品实测】C1001毫米波人体检测传感器来了!跌倒检测、睡眠监测更准确!

我们最近推出了一款全新的60G毫米波产品&#xff1a;C1001毫米波人体检测传感器。在这篇文章中&#xff0c;我们将深入测评这款产品的性能&#xff0c;并详细解析C1001毫米波人体检测传感器的功能和特性。 产品链接&#xff1a;C1001 60GHz毫米波人体检测传感器 原文链接&…

QML ScrollView 实现自动滚动到底部

先看效果,每当有新的日志,会自动添加到Text中,主要实现了ScrollView自动滑动到底部,显示最新的日志 目录 1.思路2.position分析 1.思路 在官网中scrollview并没有关于scrollview位置的设置 但是我们可以控制右边滑动条scrollbar的位置 注意position并不是一个高度数据,你可以…

Adobe Dreamweaver(DW)网页代码编辑器win/mac软件安装下载

一、Adobe DW软件概览 1.1 DW软件简介 Adobe Dreamweaver&#xff08;简称DW&#xff09;是一款功能强大的网页代码编辑器&#xff0c;由Adobe公司开发并维护。其全称为“Adobe Dreamweaver”&#xff0c;中文译为“梦想编织者”。DW集网页制作和管理网站于一身&#xff0c;支…

Allegro PCB位号重排反标原理图步骤

第一步&#xff1a;也是最重要的一步&#xff0c;备份整个工程文件夹。 防止操作过程中误操作导致工程文件出问题&#xff0c;万一出问题&#xff0c;没有备份&#xff0c;调整代价比较大 第二步&#xff1a;确认当前PCB和原理图的网表统一。 稳妥做法&#xff1a; 2a:原理图…

Linux入门——07 动静态库软硬连接

1.动静态库 静态库&#xff08;.a&#xff09;&#xff1a;程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库动态库&#xff08;.so&#xff09;&#xff1a;程序在运行的时候才去链接动态库的代码&#xff0c;多个程序共享使用库的代码。一…

如何在VMware ESXI中创建Linux虚拟机并实现异地SSH远程访问

目录 ⛳️推荐 前言 1. 在VMware ESXI中创建Ubuntu虚拟机 2. Ubuntu开启SSH远程服务 3. 安装Cpolar工具 4. 使用SSH客户端远程访问Ubuntu 5. 固定TCP公网地址 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不…

抛苹果卖银行 巴菲特到底怕什么?

文&#xff5c;琥珀食酒社 作者 | 积溪 停不下来、根本就停不下来 94岁的巴菲特还在疯狂卖股票 他到底是看到什么我们没看到的真相 对咱们普通人到底有没有参照价值&#xff1f; 我先说结论 你可以不相信有钱人的人品 但一定要知道有钱人的钱去哪儿了 尤其这个人还是巴…

机房环境监控系统

随着信息技术的飞速发展&#xff0c;数据中心作为信息处理的核心设施&#xff0c;其重要性日益凸显。数据中心内部通常包含大量的服务器、存储设备以及网络设备等关键基础设施&#xff0c;这些设备的稳定运行直接影响到业务的连续性和数据的安全性。因此&#xff0c;建立一个高…