并发容器【ConcurentHashMap、CopyOnWriteArrayList、阻塞队列、ArrayBlockingQueue】
并发容器
- 什么是并发容器?
- 同步容器:
- 并发容器:
- ConcurrentHashMap
- 结构图
- JDK1.7结构图
- JDK1.8结构图
- CopyOnWriteArrayList
- 实现原理
- 并发队列
- 阻塞队列
- ArrayBlockingQueue
转自极客时间
什么是并发容器?
在JUC包中,有一大部分是关于并发容器的,如ConcurrentHashMap,ConcurrentSkipListMap, CopyOnWriteArrayList及阻塞队列。这里将介绍使用频率、面试中出现频繁的最高的 ConcurrentHashMap和阻塞队列。
注意:这里说到的容器概念,相当于我们理解中的集合的概念。
同步容器:
Java中的集合主要分为四大类:List、Map、Set和Queue,但是并不是所有集合都是线程安全的。比 如,我们经常使用的ArrayList,HashMap,HashSet就不是线程安全的。
早期的JDK1.0中的就提供了线程安全的集合,包括Vector,Stack和Hashtable。此外还有在JDK1.2中增 加的Collections中内部SynchronizedXxx类,它们也是线程安全的集合,可以由对应 Collections.synchronizedXxx工厂方法创建。这些类实现线程安全的方式都是一样的:都是基于 synchronized这个同步关键字实现的,对每个公有方法都进行了同步,保证每次只有一个线程能访问集 合,所以它们被称为线程安全的集合(同步容器)。
并发容器:
在JDK1.5之前,JDK提供的线程安全的类都是同步集合容器。同步容器都是线程安全的,但是所有线程 对容器只能串行访问,性能很差。在JDK1.5之后引入的JUC并发包,提供的更多类型的并发容器,在性 能上做了很多改进优化,可以用来替代同步容器。它们都是针对多线程并发访问来进行设计的,我们称 它们为并发容器。
并发容器依然可以归属到我们提到的四大类:List、Map、Set 和 Queue。

这里我总结了一下它们特性和使用场景:
- List容器:
Vector:使用synchronized同步锁,数据具有强一致性。适合于对数据有强一致性要求的场 景,但性能较差。 CopyOnWriteArrayList:底层使用数组存储数据,使用复制副本实现有锁写操作,不能保 证强一致性。适合于读多写少,允许读写数据短暂不一致的高并发场景。 - Map容器
Hashtable:使用synchronized同步锁,数据具有强一致性。适合于对数据有强一致性要求的 场景,但性能较差。 ConcurrentHashMap:基于数组+链表+红黑树实现,写操作时通过synchronized同步锁将 HashEntry作为锁的粒度支持一定程度的并发写,具有弱一致性。适合于存储数据量较小,读 多写少且不要求强一致性的高并发场景。 ConcurrentSkipListMap:基于跳表实现的有序Map,使用CAS实现无锁化读写,具有弱一致 性。适合于存储数据量大,读写都比较频繁,对数据不要求强一致性的高并发场景。 - Set容器
CopyOnWriteArraySet:底层使用数组存储数据,使用复制副本实现有锁写操作,不能保证 强一致性。适合于读多写少,允许读写数据短暂不一致的场景。 ConcurrentSkipListSet:基于跳表实现的有序Set,使用CAS实现无锁化读写,具有弱一致 性。适合于存储数据量大,读写都比较频繁,对数据不要求强一致性的高并发场景。
ConcurrentHashMap
结构图
JDK1.7结构图
Java7中的ConcurrentHashMap最外层是多个segment,每个segment的底层数据结构与HashMap类 似,仍然是数组和链表组成。
每个segment独立上ReentrantLock锁,每个segment之间互不影响,提高并发效率。
默认有16个segment,最多可以同时支持16个线程并发写(操作分别分布在不同的Segment上)。这个 默认值可以在初始化时设置,但一旦初始化以后,就不可以再扩容了。

JDK1.8结构图
ConcurrentHashMap是一个存储 key/value 对的容器,并且是线程安全的。
改进一: 取消segments字段,直接采用transient volatile HashEntry<K,V>[] table保存数据,采用 table数组元素作为锁,从而实现了对每一行数据进行加锁,进一步减少并发冲突的概率。
改进二: 将原先table数组+单向链表的数据结构,变更为table数组+单向链表+红黑树的结构。查询 更快


CopyOnWriteArrayList
实现原理
CopyOnWrite 思想:是平时查询的时候,都不需要加锁,随便访问,只有在更新的时候,才会从原来的 数据复制一个副本出来,然后修改这个副本,最后把原数据替换成当前的副本。修改操作的同时,读操 作不会被阻塞,而是继续读取旧的数据。这点要跟读写锁区分一下。
public class Demo15CopyOnWriteArrayList {public static void main(String[] args) {//1、初始化CopyOnWriteArrayListList<Integer> tempList = Arrays.asList(new Integer [] {1,2});CopyOnWriteArrayList<Integer> copyList = new CopyOnWriteArrayList<>(tempList);ThreadLocal tl = new ThreadLocal();//2、模拟多线程对list进行读和写ExecutorService executorService = Executors.newFixedThreadPool(10);executorService.execute(new ReadThread(copyList));executorService.execute(new WriteThread(copyList));executorService.execute(new WriteThread(copyList));executorService.execute(new WriteThread(copyList));executorService.execute(new ReadThread(copyList));executorService.execute(new WriteThread(copyList));executorService.execute(new ReadThread(copyList));executorService.execute(new WriteThread(copyList));try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("copyList size:"+copyList.size());executorService.shutdown();}
}class ReadThread implements Runnable {private List<Integer> list;public ReadThread(List<Integer> list) {this.list = list;}@Overridepublic void run() {System.out.print("size:="+list.size()+",::");for (Integer ele : list) {System.out.print(ele + ",");}System.out.println();}
}class WriteThread implements Runnable {private List<Integer> list;public WriteThread(List<Integer> list) {this.list = list;}@Overridepublic void run() {this.list.add(9);}
}

并发队列


阻塞队列

ArrayBlockingQueue
有界,可以指定容量
公平:可以指定是否需要保证公平,如果想要保证公平,则等待最长时间的线程会被优先处理,不过会带来一定的性能损耗。
场景:有10个面试者,只有1个面试官,大厅有3个位子让面试者休息,每个人面试时间10秒,模拟所有 人面试的场景。
/*** 案例:有10个面试者,只有1个面试官,大厅有3个位子让面试者休息,每个人面试时间10秒,模拟所有人面试的场景。*/
public class Demo16ArrayBlockingQueue {static ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(3);public static void main(String[] args) {Interviewer r1 = new Interviewer(queue);//面试官Engineers e2 = new Engineers(queue);//程序员们new Thread(r1).start();new Thread(e2).start();}
}class Interviewer implements Runnable {BlockingQueue<String> queue;public Interviewer(BlockingQueue queue) {this.queue = queue;}@Overridepublic void run() {System.out.println("面试官:我准备好了,可以开始面试");String msg;try {while(!(msg = queue.take()).equals("stop")){System.out.println(msg + " 面试+开始...");TimeUnit.SECONDS.sleep(10);//面试10sSystem.out.println(msg + " 面试-结束...");}System.out.println("所有候选人都结束了");} catch (InterruptedException e) {e.printStackTrace();}}
}class Engineers implements Runnable {BlockingQueue<String> queue;public Engineers(BlockingQueue queue) {this.queue = queue;}@Overridepublic void run() {for (int i = 1; i <= 10; i++) {String candidate = "程序员" + i;try {queue.put(candidate);System.out.println(candidate+" 就坐=等待面试~");} catch (InterruptedException e) {e.printStackTrace();}}try {queue.put("stop");} catch (InterruptedException e) {e.printStackTrace();}}
}相关文章:
并发容器【ConcurentHashMap、CopyOnWriteArrayList、阻塞队列、ArrayBlockingQueue】
并发容器 什么是并发容器?同步容器:并发容器: ConcurrentHashMap结构图JDK1.7结构图JDK1.8结构图 CopyOnWriteArrayList实现原理 并发队列阻塞队列ArrayBlockingQueue 转自极客时间 什么是并发容器? 在JUC包中,有一大部分是关于并发容器的,如Concurr…...
EmoLLM-心理健康大模型
宣传一下自己最近参与的开源 https://github.com/aJupyter/EmoLLM EmoLLM-心理健康大模型 EmoLLM 探索本项目的文档 查看Demo 报告Bug 提出新特性 EmoLLM 是一个能够支持 理解用户-支持用户-帮助用户 心理健康辅导链路的心理健康大模型,由 InternLM2 指令微…...
学成在线:采用XXL-JOB任务调度方案使用FFmpeg处理视频转码业务
分片技术方案 概述 XXL-JOB并不直接提供数据处理的功能,它只会给所有注册的执行器分配好分片序号,在向执行器下发任务调度的同时携带分片总数和当前分片序号等参数 设计作业分片方案保证多个执行器之间不会查询到重复的任务,保证任务不会重复执行 任…...
计算机毕业设计 | SpringBoot大型旅游网站 旅行后台管理系统(附源码)
1, 概述 1.1 项目背景 随着互联网技术的快速发展和普及,旅游行业逐渐转向线上,越来越多的游客选择在线预订旅游产品。传统的线下旅行社模式已不能满足市场需求,因此,开发一个高效、便捷的旅游网站成为行业的迫切需求…...
蓝桥杯----凑算式
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。 比如: 68/3952/714 就是一种解法, 53/1972/486 是另一种解法. 这个算式一共有多少种解法? 注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。 代码 public class _03凑算式 {static int a[] {1,2,3…...
JCTC | 利用几何深度学习对蛋白质-配体结合pose进行等变灵活建模
Overview 该论文解决了药物开发中蛋白质-配体复合结构灵活建模的挑战。作者提出了一种名为FlexPose的新型深度学习框架,它可以直接对复杂结构进行建模,而不需要传统的采样和评分策略。 该模型结合了标量-向量双特征表示和 SE(3)等变网络设计来处理动态结…...
执行 terraform init 命令时 timeout 的解决方法
terrafrom 是一款常用来实现 IaC(基础设施即代码)的工具。通常的第一个命令往往是 terrafrom init。在执行此命令时,terrafrom 会根据已经配置好的 provdier 信息去下载安装对应云厂商的 provider。比如下面是一个腾讯云的 providerÿ…...
Docker Arthas 实战指南
Arthas 是一款强大的 Java 诊断和调试工具,它能够在生产环境中实时诊断 Java 应用,提供强大的调试功能,帮助开发者和运维人员解决各种 Java 应用的性能问题和调试挑战。本指南将介绍如何在 Docker 环境中使用 Arthas 进行实战。 官方文档 GitHub地址 …...
freertos 源码分析四 任务创建的简单分析
任务创建xTaskCreate 为TCB和TCB栈分配空间, 初始化,加入就绪任务链表 #if ( configSUPPORT_DYNAMIC_ALLOCATION 1 )BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,const char * const pcName,const configSTACK_DEPTH_TYPE usStackDepth,void *…...
二叉树的锯齿形遍历,力扣
目录 题目: 我们直接看题解吧: 快速理解解题思路小建议: 解题方法: 相似题目对比分析: 解题分析: 解题思路: 补充说明: 思路优化: 代码实现(层序遍历倒序): 题…...
避免Arrays.asList陷阱:优雅处理结构性修改的方法
临近年终,项目交付排期比较紧张,导致很多时候,Code Review 往往是走马观花,没有严格执行。最近,一个实习生就产生了一个十分低级的代码BUG。笔者感觉这个问题,对于实习生,尤其是刚入职的 应届 J…...
微信小程序(三十六)事件传参
注释很详细,直接上代码 上一篇 新增内容: 1.传参步骤 2.传参接收解构步骤 源码: index.wxml <button type"primary" bind:tap"onclick" mark:index"{{0}}" mark:remb"{{1}}" class"But&quo…...
编译原理与技术(三)——语法分析(二)自顶向下-递归下降
一、语法分析的两种方法 自顶向下(Top-down): 针对输入串,从文法的开始符号出发,尝试根据产生式规则推导(derive)出该输入串。 从根部开始构造语法树。 自底向上(Bottom-up&#…...
okhttp 的 拦截器
拦截器有很多作用,实现就是责任链模式,细节,等我有时间补上。 后面有时间更新一下。 OkHttp最核心的工作是在 getResponseWithInterceptorChain() 中进行,在进入这个方法分析之前,我们先来了 解什么是责任链模式&…...
Android:多线程下载网络图片
3.12 网络图片操作 1、通过URL请求获取网络图片 示例: 创建t_picture.xml,页面layout布局文件,一个Button按钮和一个ImageView容器显示图片。 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.a…...
跟着GPT学设计模式之原型模式
如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用对已有对象(原型)进行复制(或者叫拷贝)的方式来创建新对象&a…...
博客|基于Springboot的个人博客系统设计与实现(源码+数据库+文档)
个人博客系统目录 目录 基于Springboot的个人博客系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员功能实现 (1)用户管理 (2)文章分类管理 (3)公告信息管理 (4&#…...
【gcc】webrtc发送侧计算 丢包率
大神的分析 : 提到: 每当收到cc-feedback或者收到RR-report的时候就能统计出丢包率,在cc-controller中就会调用SendSideBandwidthEstimation::UpdatePacketsLost()去更新丢包率,同时进行码率预估 G:\CDN\rtcCli\m98\src\modules\congestion_controller\goog_cc\send_side_b…...
elementui上传文件不允许重名
需求: 用户可以多文件上传 ,在上传到服务器之前需要检查服务器中有无重名的文件,如果有会返回重名文件的名称数组,这些文件需要一个一个的向用户确认是否要覆盖重传。确认完毕后再上传到服务器。 检查文件重名: //上传…...
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Video媒体组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Video媒体组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Video媒体组件 用于播放视频文件并控制其播放状态的组件。 子组件 无 接口…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
