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

parallelStream并行流使用踩坑,集合安全

parallelStream并行流使用踩坑

parallelStream介绍

parallelStream实现的是多线程处理从而实现并行流,相较于stream的单行流处理数据的速度更快,看一下其源码会发现parallelStream是使用线程池ForkJoin来调度的。

而ForkJoinPool的默认线程数是CPU核数 - 1。如果要手动实现其线程数设置,可以构建自己的ForkJoinPool;

CountDownLatch countDownLatch = new CountDownLatch(20);int cpu = Runtime.getRuntime().availableProcessors();System.out.println(cpu);ForkJoinPool pool = new ForkJoinPool(2);List<Integer> list = IntStream.range(0, 20).boxed().collect(Collectors.toList());pool.submit(() -> {list.parallelStream().forEach(s -> {// 业务处理System.out.println("thread:" + Thread.currentThread().getName() + "value" + s);countDownLatch.countDown();});});countDownLatch.await();

问题

在开发中遇到了下面这一段代码

List<String> resultList = new ArrayList<>();
List<String> codeList = new ArrayList<>();
//向codeList中添加数据
.....
codeList.parallelStream().forEach(item->{//过滤条件后向resultList添加数据resultList.add(item);
});

使用并行流去遍历codeList后经过某些过滤再将属性值添加到resultList中。

后续在调试过程中发现,resultList中的数据量会随机少一两个数据,比如codeList中数据为1,2,3,4,5. 经过过滤后本应添加到resultList中的数据为1,2,3,4. 但是发现只加进来了1,2,3或者是1,2,4 会有数据确实的情况,本来以为是过滤条件的问题,排查后发现过滤条件没有问题,开始怀疑是并行流的问题。

简单介绍下arrayList

arrayList其实就是个动态数组类,大小可以动态调整,允许在列表任意位置进行元素的增删改查。同时可自动扩展内部数组的容量,以适应存储需求的增长。

动态扩容

  • 初始容量:arrayList的默认空参构造器时,初始容量是0,使用有参构造器时,初始容量就是传入的参数initialCapacity的值,看下源码:

public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {this.elementData = EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);}}
​/*** Constructs an empty list with an initial capacity of ten.*/public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
  • 动态扩容:添加第一个元素时,底层会创建一个新的长度为10的数组,当存储满的时候,会扩容1.5倍。这个动作是在集合添加数据的时候进行的判断

    看下源码:

    private void add(E e, Object[] elementData, int s) {if (s == elementData.length)elementData = grow();elementData[s] = e;size = s + 1;}
    private Object[] grow(int minCapacity) {int oldCapacity = elementData.length;if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {int newCapacity = ArraysSupport.newLength(oldCapacity,minCapacity - oldCapacity, /* minimum growth */oldCapacity >> 1           /* preferred growth */);return elementData = Arrays.copyOf(elementData, newCapacity);} else {return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];}}

回到原来的问题

最开始的时候,我觉得可能是数组大小不够了,在达到集合容量的前一个时同时有两个线程在往这个集合中添加数据,导致有一个数据没有插入进来,但是考虑了下,觉得如果是这样多少应该有个异常抛出来,但是在运行过程中并无异常。这时突然想到,arryList底层其实还是个数组。其实到这里就已经不言而喻了,多个线程在往list中添加数据时,都已经通过了验证容量的这一步,然后往一个数组的相同位置上放两个元素,最终结果肯定就是后面一个会把前面的一个给覆盖掉。

最终解决

最终的结果不管是对这个集合上锁 还是换成线程安全的list:Vector,Collections.synchronizedList(List<T> list),本质其实都还是类似单线程,同时只有一个线程进行操作。

(如果你只是遇到了我上面说的bug想解决,看到这里就可以了,建议直接换成stream串行。)

但是!

还有第三种线程安全的容器

CopyOnWriteArrayList

这个容器其实就是在写操作的时候复制数组,在使用时,读读操作和读写操作都不互斥。

看下源码:

public boolean add(E e) {synchronized (lock) {Object[] es = getArray();int len = es.length;es = Arrays.copyOf(es, len + 1);es[len] = e;setArray(es);return true;}}

其通过lock来实现线程同步,至于所谓的读写互斥,主要就是这里了

es = Arrays.copyOf(es, len + 1);
es[len] = e;

在添加数据时,他会先复制原来的数组然后在新的数组上面进行添加,最后再将新数组覆盖到旧的上面。如果在操作过程中切换了线程到读,此时的旧数组并未被覆盖,读取到的还是原来的数组。

虽然不会发生安全问题,但是缺陷也同样很明显,因为其每一次操作都会复制一次数组,数据量越大 操作越慢。

但是读取其实还是很快的,如果写少读多可以考虑采用这种容器。

相关文章:

parallelStream并行流使用踩坑,集合安全

parallelStream并行流使用踩坑 parallelStream介绍 parallelStream实现的是多线程处理从而实现并行流&#xff0c;相较于stream的单行流处理数据的速度更快&#xff0c;看一下其源码会发现parallelStream是使用线程池ForkJoin来调度的。 而ForkJoinPool的默认线程数是CPU核数 …...

清远榉之乡托养机构探讨:自闭症的本质辨析

当人们谈及自闭症时&#xff0c;常常会产生一个疑问&#xff1a;自闭症是精神类疾病吗&#xff1f;今天&#xff0c;清远榉之乡托养机构就来为大家解开这个疑惑。 榉之乡大龄自闭症托养机构在江苏、广东、江西等地都有分校&#xff0c;一直致力于为大龄自闭症患者提供专业的支持…...

音视频入门基础:MPEG2-TS专题(10)——PAT简介

一、引言 当某个transport packet的TS Header中的PID属性的值为0x0000时&#xff0c;该transport packet的payload为Program association table &#xff0c;即 PAT表。PAT表包含所有PMT表的目录列表&#xff0c;将program_number和PMT表的PID相关联&#xff0c;获取数据的起始…...

wordpress网站首页底部栏显示网站备案信息

一、页脚文件footer.php 例如&#xff0c;wordpress主题使用的是simple-life主题&#xff0c;服务器IP为192.168.68.89,在wordpress主题文件中有个页脚文件footer.php&#xff0c;这是一个包含网站页脚代码的文件。 footer.php 路径如下&#xff1a; /www/wwwroot/192.168.68…...

SOLIDWORKS英文,怎么修改成中文

SOLIDWORKS英文&#xff0c;怎么修改成中文 打开控制面板里的程序 选择程序与功能 找到SOLIDWORKS&#xff0c;选择并点击上方 “更改” 在跳出来的更改页面&#xff0c;选择“简体中文” 点击SOLIDWORKS界面上小齿轮&#xff0c;进入设置 取消勾选English两个相关设置 重启SO…...

简单搭建qiankun的主应用和子应用并且用Docker进行服务器部署

在node18环境下&#xff0c;用react18创建qiankun主应用和两个子应用&#xff0c;react路由用V6版本&#xff0c;都在/main路由下访问子应用&#xff0c;用Dockerfile部署到腾讯云CentOS7.6服务器的8000端口进行访问&#xff0c;且在部署过程中进行nginx配置以进行合理的路由访…...

等保三级安全架构设计方案

一、概述 等保三级&#xff0c;全称为“信息系统安全等级保护三级”&#xff0c;是根据信息安全保护的需求&#xff0c;将系统的安全保护划分为五个等级中的第三级&#xff0c;主要针对相对重要的信息系统进行保护。根据《信息系统安全等级保护基本要求》&#xff08;GB/T 222…...

【Stable Diffusion】安装教程

目录 一、python 安装教程 二、windows cuda安装教程 三、Stable Diffusion下载 四、Stable Diffusion部署&#xff08;重点&#xff09; 一、python 安装教程 &#xff08;1&#xff09;第一步下载 打开python下载页面&#xff0c;找到python3.10.9&#xff0c;点击右边…...

05—如何设计和仿真阻抗匹配网络

如何设计和仿真阻抗匹配网络 1. 介绍 在设计电路时,大部分同学只是想把布局布置的更专业,可能没有考虑串扰、电源完整性或阻抗匹配等问题。当了解天线和其他射频设备的匹配网络后,才会意识到阻抗匹配在高速和高频电路中的重要性。 但是,什么时候应该使用阻抗匹配网络?哪…...

Trimble X12助力电力管廊数据采集,为机器人巡视系统提供精准导航支持

地下电缆是一个城市重要的基础设施&#xff0c;它不仅具有规模大、范围广、空间分布复杂等特点&#xff0c;更重要的是它还承担着信息传输、能源输送等与人们生活息息相关的重要功能&#xff0c;也是一个城市赖以生存和发展的物质基础。 01、项目概述 本次项目是对某区域2公里左…...

新质驱动·科东软件受邀出席2024智能网联+低空经济暨第二届湾区汽车T9+N闭门会议

为推进广东省加快发展新质生产力&#xff0c;贯彻落实“百县千镇万村高质量发展工程”&#xff0c;推动韶关市新丰县智能网联新能源汽车、低空经济与数字技术的创新与发展&#xff0c;充分发挥湾区汽车产业链头部企业的带动作用。韶关市指导、珠三角湾区智能网联新能源汽车产业…...

UE5_建立自己的资产库

资产库需要用到一个插件&#xff1a; UAsset Browser - 直接在当前项目预览其他UE项目资产&#xff08;.uasset 文件&#xff09; - 直接迁移其他UE项目资产到当前项目 - 不用另外打开资产项目查看资产&#xff0c;迁移资产&#xff08;麻烦&#xff09; 插件官网插件文档插…...

Matlab搜索路径添加不上

发现无论是右键文件夹添加到路径&#xff0c;还是在“设置路径”中专门添加&#xff0c;我的路径始终添加不上&#xff0c;导致代码运行始终报错&#xff0c;后来将路径中的“”加号去掉后&#xff0c;就添加成功了&#xff0c;经过测试&#xff0c;路径中含有中文也可以添加成…...

跨UI发送信号

如何自定义信号 1.使用signals声明 2.返回值是void 3.在需要发送的地方使用 emit 信号名字(参数); 进行发送 4.在需要链接的地方使用connect进行链4 接 signals:void sig_addOne(int value); connect(&dlg,&SetDialog::sig_addOne,[](int value){ui->lineEdit…...

宠物领养平台构建:SpringBoot技术路线图

摘 要 如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的产生往往是为了解决现有问题而产生的。针对于宠物领养…...

uniapp App端在renderjs层渲染echarts获取不到service层id的问题

报错信息&#xff1a;Cannot read properties of undefined (reading id) at app-view.js 这样的写法App端有时在renderjs视图层获取不到server逻辑层的数据 server层 renderjs层 解决方法&#xff1a;需要把数据(id)通过server层向renderjs层传值 server层 renderjs层...

标准输入输出函数scanf()/gets()/printf()/puts()的功能和区别

前言&#xff1a; 这两个函数都是用来从标准输入设备&#xff08;通常是键盘&#xff09;读取字符串的&#xff0c;但是它们有一些区别和注意事项。 scanf函数 scanf函数是C语言中的一个输入函数&#xff0c;它可以按照指定的格式从标准输入设备&#xff08;通常是键盘&#…...

JavaScript 中的原型和原型链

JavaScript 中的原型和原型链也是一个相对较难理解透彻的知识点&#xff0c;下面结合详细例子来进行说明&#xff1a; 一、原型的概念 在 JavaScript 中&#xff0c;每个函数都有一个 prototype 属性&#xff0c;这个属性指向一个对象&#xff0c;这个对象就是所谓的 “原型对…...

tensorflow.python.framework.errors_impl.FailedPreconditionError

以下是我的报错 Traceback (most recent call last):File "e:\tool\anaconda\envs\openmmlab\lib\runpy.py", line 194, in _run_module_as_mainreturn _run_code(code, main_globals, None,File "e:\tool\anaconda\envs\openmmlab\lib\runpy.py", line 8…...

lua-cjson 例子

apt install -y lua-cjson 安装 编辑 tmp.lua cjson require "cjson" p 666 d "23.42" payload{"d":[{"pres":..(p)..,"temp":"..(d).."}]} print("payload " .. payload) j cjson.decode(payloa…...

《白帽子讲Web安全》15-16章

《白帽子讲Web安全》15-16章 《白帽子讲Web安全》15章15、Web Server配置安全15.1、Apache安全15.2、Nginx安全15.3、jBoss远程命令执行15.4、Tomcat远程命令执行15.5、HTTP Parameter Pollution15.6、小结 第四篇 互联网公司运营安全《白帽子讲Web安全》16章16、互联网业务安全…...

挑战用React封装100个组件【001】

项目地址 https://github.com/hismeyy/react-component-100 组件描述 组件适用于需要展示图文信息的场景&#xff0c;比如产品介绍、用户卡片或任何带有标题、描述和可选图片的内容展示 样式展示 代码展示 InfoCard.tsx import ./InfoCard.cssinterface InfoCardProps {ti…...

在 macOS 上安装 MongoDB Community Edition

https://www.mongodb.com/zh-cn/docs/manual/tutorial/install-mongodb-on-os-x/...

网络安全运行与维护高级 - 题库汇总百题

1. 单选题 内部信息安全管理组织中的()担负保护系统安全的责任,但工作重点偏向于监视系统的运行情况,并且对安全管理制度的贯彻执行情况进行监督和检查。 A. 安全审查和决策机构 B. 安全主管机构 C. 安全运行维护机构 D. 安全审计机构 正确答案:D 2. 单选题 下列那…...

在html页面显示一个变量,而这个变量中有xss脚本,如何安全的把这个变量原样展示出来

当你想要在HTML页面安全地展示一个可能包含XSS&#xff08;跨站脚本攻击&#xff09;脚本的变量原样内容时&#xff0c;可以通过以下几种常见的方式来实现安全展示&#xff1a; 方法一&#xff1a;使用文本节点 在JavaScript中&#xff0c;当你要将变量插入到HTML页面的某个元…...

【Linux】TCP网络编程

目录 V1_Echo_Server V2_Echo_Server多进程版本 V3_Echo_Server多线程版本 V3-1_多线程远程命令执行 V4_Echo_Server线程池版本 V1_Echo_Server TcpServer的上层调用如下&#xff0c;和UdpServer几乎一样&#xff1a; 而在InitServer中&#xff0c;大部分也和UDP那里一样&…...

openGauss你计算的表大小,有包含toast表么?

openGauss你计算的表大小&#xff0c;有包含toast表么&#xff1f; 最近有一个同事问我说“openGauss中pg_relation_size函数在计算表的大小时是否包含了大字段的大小&#xff1f;”&#xff0c;经过思考后&#xff0c;自己觉得表的大小是不包含大字段的大小的&#xff0c;然后…...

Python字典的用法(定义、增加、删除、修改、查询、遍历)

一.字典的介绍 dictionary&#xff08;字典&#xff09;是除了列表以外的 Python 中最灵活的数据类型。dict&#xff08;字典&#xff09;可以采用多个数据&#xff0c;通常用于存储描述一个物体的相关信息。 字典和列表最主要的区别是&#xff0c;字典是无序的对象集合&#x…...

分布式锁的实现原理

作者&#xff1a;来自 vivo 互联网服务器团队- Xu Yaoming 介绍分布式锁的实现原理。 一、分布式锁概述 分布式锁&#xff0c;顾名思义&#xff0c;就是在分布式环境下使用的锁。众所周知&#xff0c;在并发编程中&#xff0c;我们经常需要借助并发控制工具&#xff0c;如 mute…...

linux(centos) 环境部署,安装JDK,docker(mysql, redis,nginx,minio,nacos)

目录 1.安装JDK (非docker)1.1 将文件放在目录下&#xff1a; /usr/local/jdk1.2 解压至当前目录1.3 配置环境变量 2.安装docker2.1 验证centos内核2.2 安装软件工具包2.3 设置yum源2.4 查看仓库中所有docker版本&#xff0c;按需选择安装2.5 安装docker2.6 启动docker 并 开机…...

批量生成不同用户的pdf 文件(html样式)

技术 selenium thymeleaf itextpdf chromedriver 使用thymeleaf 将动态数据替换 使用selenium chromedriver 进行js &#xff0c;css等逻辑运算后渲染视图 使用itextpdf 将html 转为pdf 文件 html模板 <!DOCTYPE html> <html xmlns:th"http://www.thymeleaf…...

常见的排序算法

一、基于比较的排序算法 基于比较的排序算法通过比较元素之间的大小来完成排序。 1.1 冒泡排序&#xff08;Bubble Sort&#xff09; 特点&#xff1a;通过多次交换相邻元素&#xff0c;将最大&#xff08;或最小&#xff09;元素“冒泡”到序列末端。时间复杂度&#xff1a…...

从语法、功能、社区和使用场景来比较 Sass 和 LESS

一&#xff1a;可以从语法、功能、社区和使用场景来比较 Sass 和 LESS&#xff1a; 1&#xff1a;语法 原始的 Sass 采用的是缩进而不是大括号&#xff0c;后续的 Sass 版本与 LESS 一样使用与 CSS 类似的语法&#xff1a; address {.fa.fa-mobile-phone {margin: 0 3px 0 2…...

hdlbits系列verilog解答(Exams/m2014 q4b)-87

文章目录 一、问题描述二、verilog源码三、仿真结果一、问题描述 本节学习如何实现下图中的电路。 模块声明 module top_module ( input clk, input d, input ar, // asynchronous reset output q); 思路: 只是实现一种带异步复位的D触发器。 时钟边沿两种触发方式的关键字…...

Python 和 Pyecharts 对Taptap相关数据可视化分析

结果展示&#xff1a; 数据来源&#xff1a; Python爬取TapTap 热门游戏信息并存储到数据库&#xff08;详细版&#xff09; 目录 结果展示&#xff1a; 数据来源&#xff1a; Python爬取TapTap 热门游戏信息并存储到数据库&#xff08;详细版 一、引言 二、准备工作 三、…...

系统学习算法: 专题二 滑动窗口

题目一&#xff1a; 算法原理&#xff1a; 依然第一反应是暴力枚举&#xff0c;将所有的子数组都枚举出来&#xff0c;找到满足条件的长度最小的子数组&#xff0c;但是需要两层循环&#xff0c;时间复杂度来到O&#xff08;N^2&#xff09; 接下来就该思考如何进行优化 如果…...

Docker的save和export命令的区别,load和import的区别 笔记241124

Docker的save和export命令的区别,load和import的区别 解说1: Docker的save和export命令&#xff0c;以及load和import命令&#xff0c;在功能和使用场景上存在显著的区别。以下是对这两组命令的详细对比和解释&#xff1a; Docker save和export命令的区别 使用方式和目的&am…...

cad中为什么不使用C0C1C2连续,而使用G0G1G2连续

在CAD中&#xff0c;之所以使用G0、G1、G2连续而不是C0、C1、C2连续&#xff0c;主要是因为G连续性更侧重于几何空间的连续性&#xff0c;与视觉感知和制造过程更为相关。 • G0连续&#xff1a;保证曲线或曲面在连接点处没有断开&#xff0c;即位置连续。这在CAD中非常重要&a…...

Linux:makefile的使用

makefile小结&#xff1a; makefile的应用&#xff1a; 一个简单的 Makefile 文件包含一系列的“规则”&#xff0c;其样式如下&#xff1a; 目标(target)…: 依赖(prerequiries)… 命令(command) 目标(target)通常是要生成的文件的名称&#xff0c;可以是可执行文件或OBJ文件…...

局域网的网络安全

网络安全 局域网基本上都采用以广播为技术基础的以太网&#xff0c;任何两个节点之间的通信数据包&#xff0c;不仅为这两个节点的网卡所接收&#xff0c;也同时为处在同一以太网上的任何一个节点的网卡所截取。因此&#xff0c;黑客只要接入以太网上的任一节点进行侦听&#…...

【Leetcode 每日一题 - 补卡】3235. 判断矩形的两个角落是否可达

问题背景 给你两个正整数 x C o r n e r xCorner xCorner 和 y C o r n e r yCorner yCorner 和一个二维整数数组 c i r c l e s circles circles&#xff0c;其中 c i r c l e s [ i ] [ x i , y i , r i ] circles[i] [x_i, y_i, r_i] circles[i][xi​,yi​,ri​] 表示…...

Android Studio安装TalkX AI编程助手

文章目录 TalkX简介编程场景 TalkX安装TalkX编程使用ai编程助手相关文章 TalkX简介 TalkX是一款将OpenAI的GPT 3.5/4模型集成到IDE的AI编程插件。它免费提供特定场景的AI编程指导&#xff0c;帮助开发人员提高工作效率约38%&#xff0c;甚至在解决编程问题的效率上提升超过2倍…...

C++类型转换

C类型转换 1.C语言中的类型转换2.C强制类型转换2.1.static_cast2.2.reinterpret_cast2.3.const_cast2.4.dynamic_cast 3.RTTI &#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f680;系列专栏&#xff1a;【…...

241127学习日志——[CSDIY] [InternStudio] 大模型训练营 [20]

CSDIY&#xff1a;这是一个非科班学生的努力之路&#xff0c;从今天开始这个系列会长期更新&#xff0c;&#xff08;最好做到日更&#xff09;&#xff0c;我会慢慢把自己目前对CS的努力逐一上传&#xff0c;帮助那些和我一样有着梦想的玩家取得胜利&#xff01;&#xff01;&…...

关于函数式接口和编程的解析和案例实战

文章目录 匿名内部类“匿名”在哪里 函数式编程lambda表达式的条件Supplier使用示例 ConsumeracceptandThen使用场景 FunctionalBiFunctionalTriFunctional 匿名内部类 匿名内部类的学习和使用是实现lambda表达式和函数式编程的基础。是想一下&#xff0c;我们在使用接口中的方…...

基于米尔全志T527开发板的FacenetPytorch人脸识别方案

本篇测评由优秀测评者“小火苗”提供。 本文将介绍基于米尔电子MYD-LT527开发板&#xff08;米尔基于全志 T527开发板&#xff09;的FacenetPytorch人脸识别方案测试。 一、facenet_pytorch算法实现人脸识别 深度神经网络 1.简介 Facenet-PyTorch 是一个基于 PyTorch 框架实…...

Java基础面试题11:简述System.gc()和Runtime.gc()的作用?

System.gc() 和 Runtime.gc() 是 Java 中用于提示 JVM&#xff08;Java 虚拟机&#xff09;进行垃圾回收的两个方法。它们的作用类似&#xff0c;但也有一些细微的区别。下面我们来详细说明。 System.gc() 和 Runtime.gc() 的区别 简单来说&#xff0c;System.gc() 等同于 Run…...

物料理解笔记·蓝白段子线·端子线座子焊接反了怎么处理!!!

目录 蓝白端子排线 端子线座子焊接错了怎么办 端子线如何拆线 编写不易&#xff0c;请勿搬运&#xff0c;仅供学习&#xff0c;感谢理解 蓝白端子排线 蓝白端子排线&#xff0c;这种端子线常用与编码电机的接线&#xff0c;或者在板子上通过提供段子线的接口&#xff0c;通…...

string接口模拟实现2

文章目录 浅拷贝insert插入一个字符insert插入一个字符串删除erasefind(查找一个字符)\\\\\\\find(查找一个字符串:子串substr)查找的练习&#xff08;网址&#xff09;赋值operator比较大小 浅拷贝 //浅拷贝string::string(const string& str){//开一样大的空间&#xff0…...

第 42 章 - Go语言 设计模式

在Go语言中&#xff0c;设计模式是一种被广泛接受的解决常见问题的最佳实践。这些模式可以分为三类&#xff1a;创建型模式、结构型模式和行为型模式。下面我将结合案例以及源代码对这三种类型的设计模式进行详细讲解。 创建型模式 创建型模式主要关注对象的创建过程&#xf…...