并发容器(Map、List、Set)实战及其原理

一. JUC包下的并发容器

        Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map,大家熟知的这些集合类ArrayList、LinkedList、HashMap这些容器都是非线程安全的。 所以,Java先提供了同步容器供用户使用。 同步容器可以简单地理解为通过synchronized来实现同步的容器 ,比如Vector、Hashtable以及SynchronizedList等容器。这样做的代价是削弱了并发性,当多个线程共同竞争容器级的锁时,吞吐量就会降低。
        因此为了解决同步容器的性能问题,所以才有了并发容器。 java.util.concurrent 包中提供了多种并发类容器:

1.1 CopyOnWriteArrayList

        1.1.1 引入

        当我们遍历数组时加入,这时候有另一个线程也在往里添加数据的话,会报错如图:

所以当我们使用  CopyOnWriteArrayList 时就可以解决
package com.laoyang.Thread.JUC包下的并发容器;import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;/*** @author:Kevin* @create: 2023-10-19 16:47* @Description: 对应ArrayList*/public class CopyOnWriteArrayListDemo {public static void main(String[] args) {CopyOnWriteArrayList arrayList = new CopyOnWriteArrayList();//        ArrayList arrayList = new ArrayList();arrayList.add("小杨");arrayList.add("小凯");arrayList.add("小文");new Thread(() -> {arrayList.add("test");}).start();for (Object o : arrayList) {System.out.println(o.toString());}}
}

        概念

        CopyOnWriteArrayList 是 Java 中的一种线程安全的 List,它是一个可变的数组,支持并发读和写。与普通的 ArrayList 不同,它的读取操作不需要加锁,因此具有很高的并发性能。

        1.1.2 场景

        CopyOnWriteArrayList 的应用场景主要有两个方面:

        1. 读多写少的场景
        由于 CopyOnWriteArrayList 的读操作不需要加锁,因此它非常 适合在读多写少的场景中使用 。例如,一个读取频率比写入频率高得多的缓存,使用 CopyOnWriteArrayList 可以提高读取性能,并减少锁竞争的开销。
        2. 不需要实时更新的数据
        由于 CopyOnWriteArrayList 读取的数据可能不是最新的,因此它适合于不需要实时更新的数据。例如,在日志应用中,为了保证应用的性能,日志记录的操作可能被缓冲,并不是实时写入文件系统,而是在某个时刻批量写入。这种情况下,使用 CopyOnWriteArrayList 可以避免多个线程之间的竞争,提高应用的性能。

        1.1.3 黑名单实战

package com.laoyang.Thread.JUC包下的并发容器;import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;/*** @author:Kevin* @create: 2023-10-19 19:35* @Description: 黑名单实战*/public class IpDemo {private static final CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();//添加默认黑名单static {list.add("Ip0");list.add("Ip1");list.add("Ip2");}public static void main(String[] args) {Runnable runnable = new Runnable() {@Overridepublic void run() {//模拟接入try {Thread.sleep(new Random().nextInt(5000));}catch (Exception e){}String currentIP = "Ip" + new Random().nextInt(3);if (list.contains(currentIP)){System.out.println(Thread.currentThread().getName() + " IP " +currentIP + "命中黑名单,拒绝接入处理");return;}System.out.println(Thread.currentThread().getName() + " IP " +currentIP + "接入处理...");}};new Thread(runnable, "thread1").start();new Thread(runnable, "thread2").start();new Thread(runnable, "thread3").start();new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(new Random().nextInt(2000));}catch (Exception e){}String ip = "Ip3";list.add(ip);System.out.println(Thread.currentThread().getName() + " 添加了新的非法" +ip+ " + newBlackIP");}}).start();}
}

        

1.1.4 CopyOnWriteArrayList原理

        CopyOnWriteArrayList 内部使用了一种称为“写时复制”的机制。当需要进行写操作时,它会创建一个新的数组,并将原始数组的内容复制到新数组中,然后进行写操作。因此,读操作不会被写操作阻塞,读操作返回的结果可能不是最新的,但是对于许多应用场景来说,这是可以接受的。此外,由于读操作不需要加锁,因此它可以支持更高的并发度。

        1.1.5 CopyOnWriteArrayList 的缺陷

        由于写操作的时候,需要拷贝数组,会消耗内存,如果原数组的内容比较多的情况下,可能导致 young gc 或者 full gc
        不能用于实时读的场景,像拷贝数组、新增元素都需要时间,所以调用一个 set 操作后,读取到数据可能还是旧的,虽然 CopyOnWriteArrayList 能做到最终一致性,但是还是没法满足实时性要求;
        CopyOnWriteArrayList 合适读多写少的场景 ,不过这类慎用。因为谁也没法保证CopyOnWriteArrayList 到底要放置多少数据,万一数据稍微有点多,每次 add/set 都要重新复制数组,这个代价实在太高昂了。在高性能的互联网应用中,这种操作分分钟引起故障。

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

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

相关文章

深入了解RPA业务流程自动化的关键要素

在RPA业务流程自动化实施过程中&#xff0c;哪些因素起着至关重要的作用&#xff1f;这其实没有一个通用的答案&#xff0c;每一个RPA业务流程自动化的部署&#xff0c;都需要结合具体场景去调整&#xff0c;并且进行全面的规划。 首当其冲是要关注以下几点&#xff1a; 1、专…

AutoGPT:自动化GPT原理及应用实践

一、AutoGPT介绍 想象一下&#xff0c;生活在这样一个世界里&#xff0c;你有一个人工智能助手&#xff0c;它不仅能够理解你的需求&#xff0c;而且还能够与你一起学习与成长。人工智能已无缝融入我们工作、生活&#xff0c;并帮助我们有效完成各种目标。大模型技术的发展与应…

Unity之ShaderGraph如何模拟水波实现顶点波动

前言 今天我们实现类似水波纹的顶点波动效果 如下所示&#xff1a; 主要节点 Tilling And Offset&#xff1a;分别通过输入Tiling和Offset平铺和偏移输入UV的值。这通常用于细节贴图和随时间滚动的纹理。 Gradient Noise&#xff1a;根据输入UV生成梯度或Perlin噪声。生成…

【扩散模型】如何用最几毛钱生成壁纸

通过学习扩散模型了解到了统计学的美好&#xff0c;然后顺便记录下我之前文生图的基础流程~ 扩散模型简介 这次是在DataWhale的组队学习里学习的&#xff0c;HuggingFace开放扩散模型学习地址 扩散模型训练时通过对原图增加高斯噪声&#xff0c;在推理时通过降噪来得到原图&…

【UE4 材质编辑篇】1.0 shader编译逻辑

UE4新手&#xff0c;学起来&#xff08;&#xff09;文章仅记录自己的思考。 参考&#xff1a;虚幻4渲染编程(材质编辑器篇)【第一卷&#xff1a;开篇基础】 - 知乎 (zhihu.com) 开篇基础就摸不着头脑&#xff0c;原因是此前完全没有摸过UE4&#xff0c;一点一点记录吧&#x…

25台兰博基尼跑车赛道巡游!泡泡玛特MOLLY攒的局就是这么拉风

入秋以来气温逐渐转冷&#xff0c;但泡泡玛特的市场活动却持续升温&#xff1a;国内首个潮玩行业沉浸式IP主题乐园泡泡玛特城市乐园正式开园&#xff1b;2023PTS上海国际潮流玩具展&#xff1b;入驻美国第二大商场、布里斯班再拓新店等海外布局步伐不停……将广大消费者的身心带…

解决电脑出现msvcp140.dll丢失问题,msvcp140.dll丢失的详细解决方法

在我们日常使用电脑的过程中&#xff0c;可能会遇到各种问题&#xff0c;其中之一就是MSVCCP140.DLL文件缺失。这个文件是Microsoft Visual C 2015 Redistributable的一部分&#xff0c;通常用于支持一些软件或游戏运行。如果这个文件丢失或损坏&#xff0c;可能会导致程序无法…

SpringBoot集成Lettuce客户端操作Redis

目录 一、前言二、基础集成配置&#xff08;redis单节点&#xff09;2.1、POM2.2、添加配置文件application.yml2.3、编写配置文件2.4、编写启动类2.5、编写测试类测试是否连接成功 一、前言 spring-boot-starter-data-redis有两种实现 lettuce 和 jedis&#xff0c;spring bo…

手机应用app打开游戏显示连接服务器失败是什么原因?排查解决方案?

亲爱的同学们&#xff0c;有时候我们在使用手机设备时&#xff0c;可能会遇到一个很头疼的问题——连接服务器失败。这个问题不仅让我们感到困扰&#xff0c;还影响到了我们的用户体验。那么&#xff0c;我们究竟能如何解决这个问题呢&#xff1f;今天&#xff0c;笔者就和大家…

罗技鼠标接收器丢失或损坏后用另一个接收器配对的方法

本文介绍罗技鼠标在丢失、损坏其自身原有的接收器后&#xff0c;将另一个新的接收器与原有鼠标相互配对的方法。 在开始之前&#xff0c;大家需要首先查看两个内容&#xff1a;首先是原有的鼠标——大家需要查看自己的鼠标&#xff08;罗技键盘也是同样的操作&#xff09;底部&…

使用轮廓分数提升时间序列聚类的表现

我们将使用轮廓分数和一些距离指标来执行时间序列聚类实验&#xff0c;并且进行可视化 让我们看看下面的时间序列: 如果沿着y轴移动序列添加随机噪声&#xff0c;并随机化这些序列&#xff0c;那么它们几乎无法分辨&#xff0c;如下图所示-现在很难将时间序列列分组为簇: 上面…

Java_Jdbc

目录 一.JDBC概述 二.JDBC API 三.ResultSet[结果集] 四.Statement 五.PreparedStatement 六. JDBC API 总结 一.JDBC概述 JDBC 为访问不同的数据库提供了同一的接口&#xff0c;为使用着屏蔽了细节问题Java程序员使用JDBC 可以连接任何提供了 JDBC驱动的数据库系统&am…

【ES实战】ES主副分片数据不一致分析

ES主副分片数据不一致分析 文章目录 ES主副分片数据不一致分析问题描述问题重现问题分析修复方案 问题描述 在请求索引中的某一条数据时&#xff0c;时而查询有结果&#xff0c;时而无结果。两种情况交替出现。 问题重现 通过对问题数据的点查&#xff0c;确实重现了该现象 …

Redis常见面试题总结

Redis(Remote Dictionary Server) 由Salvator Sanfilippo在2009年开源的使用 ANSI C 语言编写、高性能、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库&#xff0c;并提供多种语言的 API 的非关系型数据库。 与传统数据库不同的是 Redis 的数据是存…

智能电表的功率计算方式是一样的吗?

随着科技的发展&#xff0c;智能电表已经成为了家庭和企业用电的必备设备。智能电表不仅可以实现用电量的监测和控制&#xff0c;还可以对用电负荷进行管理和优化。在智能电表的使用过程中&#xff0c;功率计算是一个重要的环节。那么&#xff0c;智能电表的功率计算方式是一样…

王兴投资5G小基站

边缘计算社区获悉&#xff0c;近期深圳佳贤通信正式完成数亿元股权融资&#xff0c;本轮融资由美团龙珠领投。本轮融资资金主要用于技术研发、市场拓展等&#xff0c;将进一步巩固和扩大佳贤通信在5G小基站领域的技术及市场领先地位。 01 佳贤通信是什么样的公司&#xff1f; 深…

【神印王座】伊莱克斯正式登场,皓晨通过永恒试炼,喜提两外挂,采儿丧失四感

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析国漫资讯。 神印王座动画更新&#xff0c;龙皓晨在雅婷与皓月的帮助下&#xff0c;两次探索悲啸洞穴后成功闯入永恒之塔。在第78集预告中&#xff0c;伊莱克斯闪亮登场&#xff0c;皓晨通过永恒试炼成为新一代死灵圣法师&…

开发小经验积累

今天使用langchain官方文档上的这个包的时候 遇到了这个报错 这个直觉判断肯定是版本问题&#xff0c;我先是去perplexity.ai搜了相关报错 后来没找到什么比较好的回答 这时候想到可以去看当前自己用的版本的langchain的源码&#xff0c;而利用vscode强大的功能&#xff0c;…

HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Slider

滑动条组件&#xff0c;通常用于快速调节设置值&#xff0c;如音量调节、亮度调节等应用场景。该组件从API Version 7开始支持。无子组件 一、接口 Slider(options?: {value?: number, min?: number, max?: number, step?: number, style?: SliderStyle, direction?: Ax…

【Linux】如何判断RS-232串口是否能正常使用

1.RS-232串口短接 使用RS-232协议的串口引脚一般如图下所示 为了让串口能够接收到自己发出的串口数据&#xff0c;需要将输出端和输入端&#xff08;RXD和TXD&#xff09;进行短接操作&#xff1a; 短接完成后&#xff0c;才能实现自发自收的功能&#xff08;走其他协议的串口清…