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 复制出一份副本,修改这个副本
于此同时,另一个线程仍然可以读取书库(从原来的数据上进行读取)
一旦这边修改完毕,就会使用修改好的这份数据,替代掉原来的数据(往往就是一个引用赋值)
上述这个过程进行修改,就不需要加锁了
但是上述操作会存在一些问题
- 当前操作的 ArrayList 不能太大(拷贝成本,不能太高)
- 更适合于一个线程去修改,而不是多个线程同时修改(多个线程去,一个线程修改)
这种场景适合于 服务器的配置更新
可以通过配置文件,来描述配置的详细内容(本身不会很大)
配置的内容会被读到内存中,再由其他的线程,读取这里的内容
但是修改这个配置内容,往往只有一个线程来修改
如果程序员修改了配置文件,通过某种操作(使用命令)让服务器重新加载配置,就可使使用 写实拷贝 的方式
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 的改良方式:
- ConcurrentHashMap 相对比上述的HashMap,最核心的改进,就是把一个全局的大锁,改进成了 每个链表独立的一把小锁
这样做大幅度降低了锁冲突的概率
一个 hash 表,有很多这样的链表,两个线程恰好同时访问一个链表的情况,本身就比较少 - 充分利用到了 CAS 特性,把一些不必要加锁的环节给省略加锁了
比如,需要使用变量记录 hash 表中的元素个数
此时,就可以使用原子操作(CAS)修改元素个数 - ConcurrentHashMap 还有一个激进的操作,针对读操作没有加锁
读和读之间,读和写之间,都不会有锁竞争
那么是否会存在“读一半 修改了一半”的数值呢?
ConcurrentHashMap 在底层编码过程中,比较谨慎的处理了一些细节
修改的时候会避免使用 ++ – 这种非原子的操作
使用 = 进行修改,本身就是原子的
读的时候,要么读的就是写之前的旧值,要么是读到写之后的心智,不会出现读到一个 一半的值
(写和写之间还是需要加锁的) - 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.…...
明明随机数
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N<100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学…...
优思学院|如何建立公司运营指标体系?如何推行六西格玛改进运营指标?
关键绩效指标 (KPI) 是测量您团队或组织朝重要商业目标进展表现如何的量化指标,组织会在多个层面使用 KPI,这视乎您想要追踪何指标而定,您可以设定全组织的、特定团队的、或甚至是个人 KPI。 良好的KPI能让公司管理者掌握组织的营运是否进度…...
vue2 echarts不同角色多个类型数据的柱状图
前端代码: 先按照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 中的数据类型包括以下几个大类: 字符串类型 数字类型 日期和时间类型 二进制类型 地理位置数据类型 JSON 数据类型 MySQL 字符串数据类型 VARCHAR:纯文本字符串,字符串长度是可变的…...
c语言单向链表
看如下代码,这是一个完整的可运行的c源文件,要注意的点: c语言程序运行不一定需要头文件NULL其实是 (void*)0,把指针赋值成(void*)0,就是防止程序员不想该指针被引用的时候被引用,引用地址为0的值程序会引起系统中断&…...
『番外篇三』Swift “乱弹”之带索引遍历异步序列(AsyncSequence)
概览 在 Swift 开发中,我们往往在遍历集合元素的同时希望获得元素对应的索引。在本课中,我们将向小伙伴们展示除 enumerated() 方法之外的几种实现思路。在玩转普通集合之后,我们将用“魔法棒”进一步搞定异步序列带索引遍历的实现。 在本篇博主中,您将学到以下内容: 概…...
学习JVM
java虚拟机 流程:helloworld.java----(javac编译)----helloworld.class-------(java运行)——JVM——机器码JVM功能 *解释和运行 *内存管理 *即时编译(跨平台-慢一点)jit (反复用到的代码 解释保存再内存里面)…...
Oracle MongoDB
听课的时候第一次碰到,可以了解一下吧,就直接开了墨者学院的靶场 #oracle数据库 Oracle数据库注入全方位利用 - 先知社区 这篇写的真的很好 1.判断注入点 当时找了半天没找到 看样子是找到了,测试一下看看 id1 and 11 时没有报错 2.判断字段…...
Linux-RedHat系统-安装 中间件 Tuxedo
安装步聚 一、中间件安装包: tuxedo121300_64_Linux_01_x86 Tuxedo下载地址: Oracle Tuxedo Downloads 二、新建用户: (创建Oracle用户时,需要root权限操作) 创建用户: # useradd oracle …...
PHP中的依赖注入是怎样的?
依赖注入(Dependency Injection,DI)是一种设计模式,它用于解耦组件之间的依赖关系,提高代码的可维护性、可测试性和灵活性。在 PHP 中,依赖注入通常通过构造函数注入、方法注入或属性注入来实现。 以下是依…...
Python求小于m的最大10个素数
为了找到小于m的最大10个素数,我们首先需要确定m的值。然后,我们可以使用一个简单的算法来检查每一个小于m的数字是否是素数。 下面是一个Python代码示例,可以找到小于m的最大10个素数: def is_prime(n): if n < 1: …...
系统的安全性设计
要设计一个安全的系统,除了要了解一些前面讲到的常用的保护手段和技术措施外,还要对系统中可能出现的安全问题或存在的安全隐患有充分的认识,这样才能对系统的安全作有针对性的设计和强化,即“知己知彼,百战百胜”。 下…...
美容店预约小程序搭建指南
随着互联网的发展,越来越多的传统行业开始尝试将业务与互联网相结合,以提供更加便捷、高效的服务。美容行业也不例外。本文将通过使用第三方制作平台,如乔拓云网,指导您如何搭建一个美观实用的美容店预约小程序,帮助您…...
AI:ElasticSearch
ElasticSearch是一款开源的分布式搜索引擎和数据分析引擎,主要用于处理海量数据并提供近实时的搜索和分析功能。它具有全文检索、结构化检索和数据分析等特点,能够满足各种复杂的搜索需求。ElasticSearch使用Java编写,可以运行在多个服务器上…...
如何用 Python 代码打包成一个可执行的 exe 文件?
将Python代码打包成可执行的EXE文件通常需要使用第三方工具,其中PyInstaller是一个流行的选择。PyInstaller可以将Python脚本打包成独立的可执行文件,无需用户安装Python解释器。 打包Python代码成EXE文件的步骤 步骤1:安装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模板,简约大气视频剪辑素材PR项目工程文件(包含手机竖屏分辨率),包含24个媒体占位符和9个文本占位符。可以编辑和自定义文本占位符和媒体占位符。用来展示照片视频制作。包含视频教程。 来自PR模板网:http…...
Guarded Suspension(担保挂起)设计模式
当线程访问某个对象时,发现条件不满足,暂时挂起等待条件满足时再次访问。Guarded Suspension模式是一个非常基础的模式,主要关注(临界值)不满足时将操作的线程正确挂起,以防止出现数据不一致或者操作超过临…...
禾匠榜店商城系统 RCE漏洞复现
0x01 产品简介 禾匠榜店商城系统是浙江禾匠信息科技有限公司的一套基于PHP和MySQL的商城系统。 0x02 漏洞概述 禾匠榜店商城系统的api/testOrderSubmit模块下的preview方法存在命令执行漏洞,攻击者可以向服务器写入木马文件,直接获取服务器权限 0x03 漏洞概述 FOFA:bod…...
Python移动未标注的图片数据集
Python移动未标注的图片数据集 前言前提条件相关介绍实验环境Python移动未标注的图片数据集情况一:有图,无标注文件代码实现输出结果 情况二:有图,有标注文件,但标注信息为空代码实现输出结果 情况一与情况二同时都考虑…...
判断css文字发生了截断,增加悬浮提示
示例: 固定显示宽度,溢出显示...,利用了css的属性,想要实现成下面这样: 针对溢出的文字,hover显示全部。 提示很好加,使用tooltip组件就行了,难点是如何判断是否发生了文字溢出。…...
day33-37-SpringBootV12(整合Spring,SpringMVC,Mybatis,日志,api测试等框架)
ssm spring --> applicationContext.xml配置文件 springmvc --> springmvc.xml配置文件 mybatis —> mybatis-config.xml配置文件 —> springboot优化了之前的框架配置,思想是约定大于配置 一、引言 1.1 初始化配置 为了使用SSM框架去开发,准备SSM…...
如何处理好面试中的“压力测试”?
作为一名求职者,在面试时有时遇到的是压力测试,有时则遇到的是一些无良企业单位,究竟如何把握忍耐的限度,才合格当一个能经受压力的员工,才能避免对无良单位的一味隐忍! 压力面试是指有意制造紧张,以了解求…...
大数据----31.hbase安装启动
二.Hbase安装 先前安装: Zookeeper 正常部署 首先保证 Zookeeper 集群的正常部署,并启动之。 三台机器都执行:zkServer.sh startHadoop 正常部署 Hadoop 集群的正常部署并启动。 主节点上进行 :start-all.sh 1.HBase 的获取 一定…...
ChatGPT Plus重新开启订阅
12月14日凌晨,OpenAI首席执行官Sam Altman在社交平台宣布,终于找到了更多的GPU算力,重新开启订阅ChatGPT Plus。 上个月15日,OpenAI就因为算力不足,以及用户激增等原因暂停了ChatGPT Plus订阅。 Sam表示,在…...
C#科学绘图之scottPlot绘制多个图像
文章目录 示例移除图像图例信号图 scott系列:绘图初步 示例 从名字就能看出,ScottPlot的绘图函数AddScatter的作用是为图窗添加数据点,换言之,每调用一次AddScatter,就可以在图窗中添加一组图像。下面添加两个按钮&a…...
二百一十五、Flume——Flume拓扑结构之复制和多路复用的开发案例(亲测,附截图)
一、目的 对于Flume的复制和多路复用拓扑结构,进行一个小的开发测试 二、复制和多路复用拓扑结构 (一)结构含义 Flume 支持将事件流向一个或者多个目的地。 (二)结构特征 这种模式可以将相同数据复制到多个channe…...
Leetcode—2962.统计最大元素出现至少 K 次的子数组【中等】
2023每日刷题(五十六) 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阶段:将原始数据分割成若干个小块,每个小块由一个Map任务处理。Map任务将小块中的每个数据项映射成为一个键值对,其中键为时间戳,值为车流量。2.Shuffle阶段:将Map任务输出…...
网站404怎么做视频教程/微网站
今天看 SQL Server resource kit 的时候提到了系统的可用性 (Availablity)发现自己以前有很多认识还是很不正确的。1. 99.9 很容易保证?很难保证。 99.9 也就是三九,呵呵。要求一年只能有8.8 小时的offline 时间,算到每个月就更少了。所以99.…...
wordpress与新浪博客/军事最新消息
今天使用panelvar包时,显示我的R版本太低,报警告: package panelvar is not available(for R version 3.4.3)对于此类问题解决方法,可以使用以下语句来解决: source("http://bioconductor.org/biocLite.R"…...
网站备案证件/外包网络推广营销
idea 打开 vue 项目爆红 有可能是项目中有这个文件 .eslintrc.js 有时间可以研究怎么写这个配置 我是直接注释掉了。。。...
网站服务器有什么区别/培训班该如何建站
JsoupJsoup 是一款轻量高效的 html 文档解析工具,可类比 xml 中的 dom4j 、jdomJsoup中的基本类DocumentHtml 整个文档在内容中的数据结构,继承 ElementElement标记元素的数据结构 ,继承 NodeElementsElement 的集合,继承 ArrayLi…...
海淘返利网站怎么做/网页分析工具
结合二叉树和Graham扫描技术的高效Delaunay三角网构建算法 摘 要:为了提高不规则三角网的构建速度,提出了一种高效构建Delaunay三角网算法。首先对平面上的离散点集按一定的阈值进行分块,建立子块索引二叉树,然后利用Graham扫描技术对各子块构建Delaunay三角网,最后自底向上…...
郑州正规的网站制作价钱/合肥网站推广优化
文章 计算机视觉课程第一讲-VS2015环境配置开发库OpenCV安装读取显示图像程序 计算机视觉课程第二讲-OpenCV4读取、显示、保存-视频&摄像头数据 计算机视觉课程第三讲-形态学处理:膨胀、腐蚀、开运算、闭运算、形态学梯度、顶帽、黑帽、击中击不中变换 计算…...