当前位置: 首页 > 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…...

Python移动未标注的图片数据集

Python移动未标注的图片数据集 前言前提条件相关介绍实验环境Python移动未标注的图片数据集情况一&#xff1a;有图&#xff0c;无标注文件代码实现输出结果 情况二&#xff1a;有图&#xff0c;有标注文件&#xff0c;但标注信息为空代码实现输出结果 情况一与情况二同时都考虑…...

判断css文字发生了截断,增加悬浮提示

示例&#xff1a; 固定显示宽度&#xff0c;溢出显示...&#xff0c;利用了css的属性&#xff0c;想要实现成下面这样&#xff1a; 针对溢出的文字&#xff0c;hover显示全部。 提示很好加&#xff0c;使用tooltip组件就行了&#xff0c;难点是如何判断是否发生了文字溢出。…...

day33-37-SpringBootV12(整合Spring,SpringMVC,Mybatis,日志,api测试等框架)

ssm spring --> applicationContext.xml配置文件 springmvc --> springmvc.xml配置文件 mybatis —> mybatis-config.xml配置文件 —> springboot优化了之前的框架配置,思想是约定大于配置 一、引言 1.1 初始化配置 为了使用SSM框架去开发&#xff0c;准备SSM…...

如何处理好面试中的“压力测试”?

作为一名求职者&#xff0c;在面试时有时遇到的是压力测试&#xff0c;有时则遇到的是一些无良企业单位&#xff0c;究竟如何把握忍耐的限度&#xff0c;才合格当一个能经受压力的员工&#xff0c;才能避免对无良单位的一味隐忍! 压力面试是指有意制造紧张&#xff0c;以了解求…...

大数据----31.hbase安装启动

二.Hbase安装 先前安装&#xff1a; Zookeeper 正常部署 首先保证 Zookeeper 集群的正常部署&#xff0c;并启动之。 三台机器都执行&#xff1a;zkServer.sh startHadoop 正常部署 Hadoop 集群的正常部署并启动。 主节点上进行 &#xff1a;start-all.sh 1.HBase 的获取 一定…...

ChatGPT Plus重新开启订阅

12月14日凌晨&#xff0c;OpenAI首席执行官Sam Altman在社交平台宣布&#xff0c;终于找到了更多的GPU算力&#xff0c;重新开启订阅ChatGPT Plus。 上个月15日&#xff0c;OpenAI就因为算力不足&#xff0c;以及用户激增等原因暂停了ChatGPT Plus订阅。 Sam表示&#xff0c;在…...

C#科学绘图之scottPlot绘制多个图像

文章目录 示例移除图像图例信号图 scott系列&#xff1a;绘图初步 示例 从名字就能看出&#xff0c;ScottPlot的绘图函数AddScatter的作用是为图窗添加数据点&#xff0c;换言之&#xff0c;每调用一次AddScatter&#xff0c;就可以在图窗中添加一组图像。下面添加两个按钮&a…...

二百一十五、Flume——Flume拓扑结构之复制和多路复用的开发案例(亲测,附截图)

一、目的 对于Flume的复制和多路复用拓扑结构&#xff0c;进行一个小的开发测试 二、复制和多路复用拓扑结构 &#xff08;一&#xff09;结构含义 Flume 支持将事件流向一个或者多个目的地。 &#xff08;二&#xff09;结构特征 这种模式可以将相同数据复制到多个channe…...

Leetcode—2962.统计最大元素出现至少 K 次的子数组【中等】

2023每日刷题&#xff08;五十六&#xff09; Leetcode—2962.统计最大元素出现至少 K 次的子数组 滑动窗口算法思想 参考的灵神思路 实现代码 class Solution { public:long long countSubarrays(vector<int>& nums, int k) {int n nums.size();long long ans…...

MapReduce模拟统计每日车流量-解决方案

MapReduce模拟统计每日车流量-解决方案 1.Map阶段&#xff1a;将原始数据分割成若干个小块&#xff0c;每个小块由一个Map任务处理。Map任务将小块中的每个数据项映射成为一个键值对&#xff0c;其中键为时间戳&#xff0c;值为车流量。2.Shuffle阶段&#xff1a;将Map任务输出…...

网站404怎么做视频教程/微网站

今天看 SQL Server resource kit 的时候提到了系统的可用性 (Availablity)发现自己以前有很多认识还是很不正确的。1. 99.9 很容易保证&#xff1f;很难保证。 99.9 也就是三九&#xff0c;呵呵。要求一年只能有8.8 小时的offline 时间&#xff0c;算到每个月就更少了。所以99.…...

wordpress与新浪博客/军事最新消息

今天使用panelvar包时&#xff0c;显示我的R版本太低&#xff0c;报警告&#xff1a; package panelvar is not available(for R version 3.4.3)对于此类问题解决方法&#xff0c;可以使用以下语句来解决&#xff1a; source("http://bioconductor.org/biocLite.R"…...

网站备案证件/外包网络推广营销

idea 打开 vue 项目爆红 有可能是项目中有这个文件 .eslintrc.js 有时间可以研究怎么写这个配置 我是直接注释掉了。。。...

网站服务器有什么区别/培训班该如何建站

JsoupJsoup 是一款轻量高效的 html 文档解析工具&#xff0c;可类比 xml 中的 dom4j 、jdomJsoup中的基本类DocumentHtml 整个文档在内容中的数据结构&#xff0c;继承 ElementElement标记元素的数据结构 &#xff0c;继承 NodeElementsElement 的集合&#xff0c;继承 ArrayLi…...

海淘返利网站怎么做/网页分析工具

结合二叉树和Graham扫描技术的高效Delaunay三角网构建算法 摘 要:为了提高不规则三角网的构建速度,提出了一种高效构建Delaunay三角网算法。首先对平面上的离散点集按一定的阈值进行分块,建立子块索引二叉树,然后利用Graham扫描技术对各子块构建Delaunay三角网,最后自底向上…...

郑州正规的网站制作价钱/合肥网站推广优化

文章 计算机视觉课程第一讲-VS2015环境配置开发库OpenCV安装读取显示图像程序 计算机视觉课程第二讲-OpenCV4读取、显示、保存-视频&摄像头数据 计算机视觉课程第三讲-形态学处理&#xff1a;膨胀、腐蚀、开运算、闭运算、形态学梯度、顶帽、黑帽、击中击不中变换 计算…...