当前位置: 首页 > news >正文

Java EE 多线程之线程安全的集合类

文章目录

  • 1. 多线程环境使用 ArrayList
    • 1. 1 Collections.synchronizedList(new ArrayList)
    • 1.2 CopyOnWriteArrayList
  • 2. 多线程环境使用队列
    • 2.1 ArrayBlockingQueue
    • 2.2 LinkedBlockingQueue
    • 2.3 PriorityBlockingQueue
    • 2.4 TransferQueue
  • 3. 多线程环境使用哈希表
    • 3.1 Hashtable
    • 3.2 ConcurrentHashMap

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

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

针对这些线程不安全的集合类,要想在多线程环境下使用,就需要考虑好 线程安全问题了(加锁)

同时,标准库,也给我们提供了一些搭配的组件,保证线程安全

1. 多线程环境使用 ArrayList

1. 1 Collections.synchronizedList(new ArrayList)

Collections.synchronizedList(new ArrayList)
这个东西会返回一个新的对象,这个新的对象,就相当于给 ArrayList 套了一层外衣
这个外衣就是在方法上直接使用 synchronized 的

1.2 CopyOnWriteArrayList

CopyOnWriteArrayList 称为写实拷贝

比如,两个线程使用同一个 ArrayList ,可能会读,也可能会修改

如果要是两个线程读,可以直接进行读
如果某个线程需要进行修改,就把 ArrayList 复制出一份副本,修改这个副本
于此同时,另一个线程仍然可以读取书库(从原来的数据上进行读取)
一旦这边修改完毕,就会使用修改好的这份数据,替代掉原来的数据(往往就是一个引用赋值)

上述这个过程进行修改,就不需要加锁了


但是上述操作会存在一些问题

  1. 当前操作的 ArrayList 不能太大(拷贝成本,不能太高)
  2. 更适合于一个线程去修改,而不是多个线程同时修改(多个线程去,一个线程修改)

这种场景适合于 服务器的配置更新

可以通过配置文件,来描述配置的详细内容(本身不会很大)

配置的内容会被读到内存中,再由其他的线程,读取这里的内容
但是修改这个配置内容,往往只有一个线程来修改

如果程序员修改了配置文件,通过某种操作(使用命令)让服务器重新加载配置,就可使使用 写实拷贝 的方式

2. 多线程环境使用队列

2.1 ArrayBlockingQueue

基于数组实现的阻塞队列

2.2 LinkedBlockingQueue

基于链表实现的阻塞队列

2.3 PriorityBlockingQueue

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

2.4 TransferQueue

最多只包含⼀个元素的阻塞队列

3. 多线程环境使用哈希表

HashMap 本⾝不是线程安全的
在多线程环境下使⽤哈希表可以使⽤:
• Hashtable
• ConcurrentHashMap

3.1 Hashtable

Hashtable 保证线程安全,主要就是给关键方法,加上 synchronized
synchronized 是直接加到方法上的(相当于给 this 加锁)

只要两个线程,在同时操作同一个 Hashtable 就会出现锁冲突


但是实际上,对于哈希表来时,锁不一定非要这么加,有些情况,其实并不涉及到线程安全问题

两个不同的 key 映射到同一个数组下标上就会出现 hash 冲突
这个时候,我们可以使用链表来解决 hash 冲突
在这里插入图片描述
按照上述这样的方式,并且在不考虑触发扩容的前提下
操作不同的链表的时候就是线程安全的

相比之下,如果两个线程,操作的是同一个链表,会容易出现问题

如果两个线程,操作的是不同的链表,就根本不用加锁,只有说操作的是同一个链表才需要加锁

3.2 ConcurrentHashMap

ConcurrentHashMap 的改良方式:

  1. ConcurrentHashMap 相对比上述的HashMap,最核心的改进,就是把一个全局的大锁,改进成了 每个链表独立的一把小锁
    这样做大幅度降低了锁冲突的概率
    一个 hash 表,有很多这样的链表,两个线程恰好同时访问一个链表的情况,本身就比较少
  2. 充分利用到了 CAS 特性,把一些不必要加锁的环节给省略加锁了
    比如,需要使用变量记录 hash 表中的元素个数
    此时,就可以使用原子操作(CAS)修改元素个数
  3. ConcurrentHashMap 还有一个激进的操作,针对读操作没有加锁
    读和读之间,读和写之间,都不会有锁竞争
    那么是否会存在“读一半 修改了一半”的数值呢?
    ConcurrentHashMap 在底层编码过程中,比较谨慎的处理了一些细节
    修改的时候会避免使用 ++ – 这种非原子的操作
    使用 = 进行修改,本身就是原子的
    读的时候,要么读的就是写之前的旧值,要么是读到写之后的心智,不会出现读到一个 一半的值
    (写和写之间还是需要加锁的)
  4. ConcurrentHashMap 针对扩容操作,做出了单独的优化
    本身 Hashtable 或者 HashMap 在扩容的时候,都是需要把所有的元素都拷贝一遍(如果元素很多,拷贝就比较耗时)
    比如,用户访问 1000 次,999 次都很流畅,其中一次就卡了(正好这一次触发扩容,导致出现卡顿)
    ConcurrentHashMap 的优化方式就是“化整为零
    一旦需要扩容,确实需要搬运,不是在一次操作中搬运完成,而是分成多次 来搬运
    每次只搬运一部分数据,这样就可以避免这单次操作过于卡顿

ConcurrentHashMap 基本的使用方法和普通的 HashMap 完全一样

在第一点中,我们是怎么把每个链表单独加锁的呢?
其实就是把每个链表的头结点,作为锁对象
synchronized 可以使用任意对象作为锁对象

在这个时候,我们有的时候会提到分段锁
什么是分段锁呢?
在 java 8 之前, ConcurrentHashMap 就是基于分段锁的方式实现的
等到 java 8 开始之后,就成了直接在链表头结点,加锁的形式

相关文章:

Java EE 多线程之线程安全的集合类

文章目录 1. 多线程环境使用 ArrayList1. 1 Collections.synchronizedList(new ArrayList)1.2 CopyOnWriteArrayList 2. 多线程环境使用队列2.1 ArrayBlockingQueue2.2 LinkedBlockingQueue2.3 PriorityBlockingQueue2.4 TransferQueue 3. 多线程环境使用哈希表3.1 Hashtable3.…...

明明随机数

明明想在学校中请一些同学一起做一项问卷调查&#xff0c;为了实验的客观性&#xff0c;他先用计算机生成了N个1到1000之间的随机整数(N<100)&#xff0c;对于其中重复的数字&#xff0c;只保留一个&#xff0c;把其余相同的数去掉&#xff0c;不同的数对应着不同的学生的学…...

优思学院|如何建立公司运营指标体系?如何推行六西格玛改进运营指标?

关键绩效指标 (KPI) 是测量您团队或组织朝重要商业目标进展表现如何的量化指标&#xff0c;组织会在多个层面使用 KPI&#xff0c;这视乎您想要追踪何指标而定&#xff0c;您可以设定全组织的、特定团队的、或甚至是个人 KPI。 良好的KPI能让公司管理者掌握组织的营运是否进度…...

vue2 echarts不同角色多个类型数据的柱状图

前端代码&#xff1a; 先按照echarts插件。在页面里引用 import * as echarts from "echarts";设置div <div style"width:100%;height:250px;margin-top: 4px;" id"addressChart"></div>方法: addressEcharts() {const option {g…...

Mysql表的数据类型

数据类型 https://www.sjkjc.com/mysql/varchar/ MySQL 中的数据类型包括以下几个大类&#xff1a; 字符串类型 数字类型 日期和时间类型 二进制类型 地理位置数据类型 JSON 数据类型 MySQL 字符串数据类型 VARCHAR&#xff1a;纯文本字符串&#xff0c;字符串长度是可变的…...

c语言单向链表

看如下代码&#xff0c;这是一个完整的可运行的c源文件&#xff0c;要注意的点&#xff1a; c语言程序运行不一定需要头文件NULL其实是 (void*)0&#xff0c;把指针赋值成(void*)0,就是防止程序员不想该指针被引用的时候被引用&#xff0c;引用地址为0的值程序会引起系统中断&…...

『番外篇三』Swift “乱弹”之带索引遍历异步序列(AsyncSequence)

概览 在 Swift 开发中,我们往往在遍历集合元素的同时希望获得元素对应的索引。在本课中,我们将向小伙伴们展示除 enumerated() 方法之外的几种实现思路。在玩转普通集合之后,我们将用“魔法棒”进一步搞定异步序列带索引遍历的实现。 在本篇博主中,您将学到以下内容: 概…...

学习JVM

java虚拟机 流程&#xff1a;helloworld.java----(javac编译)----helloworld.class-------(java运行)——JVM——机器码JVM功能 *解释和运行 *内存管理 *即时编译&#xff08;跨平台-慢一点&#xff09;jit &#xff08;反复用到的代码 解释保存再内存里面&#xff09;…...

Oracle MongoDB

听课的时候第一次碰到&#xff0c;可以了解一下吧&#xff0c;就直接开了墨者学院的靶场 #oracle数据库 Oracle数据库注入全方位利用 - 先知社区 这篇写的真的很好 1.判断注入点 当时找了半天没找到 看样子是找到了&#xff0c;测试一下看看 id1 and 11 时没有报错 2.判断字段…...

Linux-RedHat系统-安装 中间件 Tuxedo

安装步聚 一、中间件安装包&#xff1a; tuxedo121300_64_Linux_01_x86 Tuxedo下载地址&#xff1a; Oracle Tuxedo Downloads 二、新建用户&#xff1a; &#xff08;创建Oracle用户时&#xff0c;需要root权限操作&#xff09; 创建用户&#xff1a; # useradd oracle …...

PHP中的依赖注入是怎样的?

依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;是一种设计模式&#xff0c;它用于解耦组件之间的依赖关系&#xff0c;提高代码的可维护性、可测试性和灵活性。在 PHP 中&#xff0c;依赖注入通常通过构造函数注入、方法注入或属性注入来实现。 以下是依…...

Python求小于m的最大10个素数

为了找到小于m的最大10个素数&#xff0c;我们首先需要确定m的值。然后&#xff0c;我们可以使用一个简单的算法来检查每一个小于m的数字是否是素数。 下面是一个Python代码示例&#xff0c;可以找到小于m的最大10个素数&#xff1a; def is_prime(n): if n < 1: …...

系统的安全性设计

要设计一个安全的系统&#xff0c;除了要了解一些前面讲到的常用的保护手段和技术措施外&#xff0c;还要对系统中可能出现的安全问题或存在的安全隐患有充分的认识&#xff0c;这样才能对系统的安全作有针对性的设计和强化&#xff0c;即“知己知彼&#xff0c;百战百胜”。 下…...

美容店预约小程序搭建指南

随着互联网的发展&#xff0c;越来越多的传统行业开始尝试将业务与互联网相结合&#xff0c;以提供更加便捷、高效的服务。美容行业也不例外。本文将通过使用第三方制作平台&#xff0c;如乔拓云网&#xff0c;指导您如何搭建一个美观实用的美容店预约小程序&#xff0c;帮助您…...

AI:ElasticSearch

ElasticSearch是一款开源的分布式搜索引擎和数据分析引擎&#xff0c;主要用于处理海量数据并提供近实时的搜索和分析功能。它具有全文检索、结构化检索和数据分析等特点&#xff0c;能够满足各种复杂的搜索需求。ElasticSearch使用Java编写&#xff0c;可以运行在多个服务器上…...

如何用 Python 代码打包成一个可执行的 exe 文件?

将Python代码打包成可执行的EXE文件通常需要使用第三方工具&#xff0c;其中PyInstaller是一个流行的选择。PyInstaller可以将Python脚本打包成独立的可执行文件&#xff0c;无需用户安装Python解释器。 打包Python代码成EXE文件的步骤 步骤1&#xff1a;安装PyInstaller 首…...

【Hive】——CLI客户端(bin/beeline,bin/hive)

1 HiveServer、HiveServer2 2 bin/hive 、bin/beeline 区别 3 bin/hive 客户端 hive-site.xml 配置远程 MateStore 地址 XML <?xml version"1.0" encoding"UTF-8" standalone"no"?> <?xml-stylesheet type"text/xsl" hre…...

简约大气视频制作模板PR剪辑素材PR项目工程文件

Premiere Pro模板&#xff0c;简约大气视频剪辑素材PR项目工程文件&#xff08;包含手机竖屏分辨率&#xff09;&#xff0c;包含24个媒体占位符和9个文本占位符。可以编辑和自定义文本占位符和媒体占位符。用来展示照片视频制作。包含视频教程。 来自PR模板网&#xff1a;http…...

Guarded Suspension(担保挂起)设计模式

当线程访问某个对象时&#xff0c;发现条件不满足&#xff0c;暂时挂起等待条件满足时再次访问。Guarded Suspension模式是一个非常基础的模式&#xff0c;主要关注&#xff08;临界值&#xff09;不满足时将操作的线程正确挂起&#xff0c;以防止出现数据不一致或者操作超过临…...

禾匠榜店商城系统 RCE漏洞复现

0x01 产品简介 禾匠榜店商城系统是浙江禾匠信息科技有限公司的一套基于PHP和MySQL的商城系统。 0x02 漏洞概述 禾匠榜店商城系统的api/testOrderSubmit模块下的preview方法存在命令执行漏洞,攻击者可以向服务器写入木马文件,直接获取服务器权限 0x03 漏洞概述 FOFA:bod…...

ElevenLabs语音合成接入视频工作流:3步完成API对接,72小时内提升配音效率300%

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;ElevenLabs语音合成接入视频工作流&#xff1a;3步完成API对接&#xff0c;72小时内提升配音效率300% ElevenLabs 的高质量、低延迟语音合成 API 已成为专业视频内容生产链路中的关键组件。其情感化语音…...

3个场景解锁小爱音箱音乐自由:开源神器XiaoMusic的终极指南

3个场景解锁小爱音箱音乐自由&#xff1a;开源神器XiaoMusic的终极指南 【免费下载链接】xiaomusic 使用小爱音箱播放音乐&#xff0c;音乐使用 yt-dlp 下载。 项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic 还在为小爱音箱的音乐播放限制而烦恼吗&…...

开关电源选型保姆级指南:从LRS-200-24到NDR-480-24,手把手教你算功率、看效率、避高温降额

开关电源选型实战手册&#xff1a;从基础参数到工业场景避坑指南 工业电源选型的三大认知误区 第一次为自动化产线选配开关电源时&#xff0c;我犯了个典型错误——直接按照设备铭牌功率总和选择了LRS-200-24型号。结果设备联调当天&#xff0c;传送带电机频繁重启&#xff0c;…...

白细胞介素(Interleukins, ILs)的研究进展与生物学功能

白细胞介素&#xff08;Interleukins, ILs&#xff09;是一类由白细胞产生并参与细胞间信号传导的细胞因子&#xff0c;自1979年命名以来&#xff0c;已成为免疫学研究的核心领域。目前已发现至少38种白细胞介素&#xff0c;其作为小分子多肽或糖蛋白&#xff0c;通过调控免疫细…...

BLE心率监测服务开发:从GATT协议到CCCD通知机制的完整实现

1. 项目概述如果你正在开发一款智能手环、心率带或者任何需要实时上报生理数据的可穿戴设备&#xff0c;那么蓝牙低功耗&#xff08;BLE&#xff09;的心率监测服务&#xff08;Heart Rate Service, HRS&#xff09;几乎是你绕不开的核心功能。这个看似标准的服务&#xff0c;其…...

桌面3D扫描技术解析:从结构光原理到实战避坑指南

1. 从工业殿堂到桌面工坊&#xff1a;3D扫描的平民化浪潮 几年前&#xff0c;如果你跟人提起3D扫描&#xff0c;脑海里浮现的画面多半是电影特效工作室里&#xff0c;演员身上贴满标记点&#xff0c;被一圈昂贵的专业相机环绕&#xff1b;或者是汽车制造车间里&#xff0c;巨大…...

构建AI模型API桥接器:实现OpenAI格式与私有模型服务的无缝对接

1. 项目概述&#xff1a;连接两个世界的桥梁最近在折腾一些AI相关的项目时&#xff0c;遇到了一个挺有意思的“桥接”需求。简单来说&#xff0c;我手头有一套基于OpenAI API的成熟应用逻辑&#xff0c;但出于性能、成本或者特定环境限制的考虑&#xff0c;我希望后端能无缝切换…...

为LLM构建安全代码执行环境:e2b代码解释器实战指南

1. 项目概述&#xff1a;当LLM拥有一个真正的代码执行环境最近在折腾AI应用开发&#xff0c;特别是想让大语言模型&#xff08;LLM&#xff09;不只是“纸上谈兵”&#xff0c;而是能真正动手执行代码、处理数据、生成图表。这让我找到了一个非常有意思的项目&#xff1a;e2b-d…...

星闪测距性能分析

环境HiSpark开发平台&#xff0c;两块BS21E丢包率1分钟内75次测距数据中&#xff0c;约有6次左右的数据是无效或者丢失&#xff0c;可以通过一些滤波算法过滤&#xff0c;完全可以满足小车定位的需要。测距精度目前使用的测距方案是RSSI信号强度与IQ信号结合&#xff0c;精度达…...

量子电路编译与Trotter分解技术详解

1. 量子电路编译基础与Trotter分解原理量子电路编译是将抽象的量子算法转化为可在实际量子硬件上执行的低级量子门序列的过程。在模拟量子系统动力学时&#xff0c;Trotter-Suzuki分解是最常用的技术之一&#xff0c;它允许我们将连续的量子演化分解为离散的门操作序列。1.1 Tr…...