Java并行流parallelStream()下InheritableThreadLocal引起的问题
Java并行流parallelStream()下InheritableThreadLocal引起的问题
引起问题的代码。
List orgs00 = Arrays.asList(new Org("aaa"),new Org("bbb"),new Org("aa0"));List orgs = orgs00.parallelStream() .map(org -> {// 模拟从数据库中获取 Org 对象的操作// 这里可以是实际的数据库查询操作ConditionImpl cmd = new ConditionImpl();cmd.op("orgName", Op.eq, org.getOrgName());
// cmd.orderBy("name", OrderType.ASC);System.out.println("-----------------111111111111111111111111-");List select1 = getSuidRich().select(new Org(), cmd); //语句1:这句会调用数据库return new Org(org.getOrgName());}).collect(Collectors.toList());问题:语句1调用的方法有条词句:private static ThreadLocal>> sqlPreValueLocal;经过orgs00.parallelStream().map()) 执行调用语句1,sqlPreValueLocal是同一个本地变量吗?
并行流场景下使用 ThreadLocal, sqlPreValueLocal = new InheritableThreadLocal<>(); //语句1
或者
sqlPreValueLocal = new ThreadLocal<>();//语句2
用语句1有时上下文丢失,但用语句2不会, 可以解释为什么吗?
在并行流场景下,使用InheritableThreadLocal和ThreadLocal可能会出现不同的行为,导致上下文丢失的问题。下面我会解释一下为什么语句1有时会出现上下文丢失,而语句2不会。
- 使用
InheritableThreadLocal(语句1):
InheritableThreadLocal会使子线程继承父线程中的ThreadLocal变量的值。在并行流中,由于线程池的调度机制,父线程有可能会参与到并行流线程池的调度。如果父线程的上下文在某个时刻被清理,那么后续拷贝到子线程的上下文可能为空,导致上下文丢失的问题。这种情况可能会导致语句1有时会出现上下文丢失的情况。
- 使用
ThreadLocal(语句2):
ThreadLocal不具备继承性,子线程不会继承父线程中的ThreadLocal变量的值。因此,在并行流中使用ThreadLocal时,不会出现父线程上下文被清理导致的上下文丢失问题。每个线程都有自己独立的ThreadLocal副本,不会受到父线程的影响。
综上所述,使用InheritableThreadLocal在并行流场景下可能会出现上下文丢失的问题,而使用ThreadLocal则不会受到这种影响。因此,如果在并行流中需要使用ThreadLocal来传递上下文,可以考虑使用ThreadLocal而不是InheritableThreadLocal,以避免上下文丢失的情况。
原因在于并行流的设计比较特殊,父线程也有可能参与到并行流线程池的调度,那如果 方法被父线程执行,那么父线程的上下文会被清理。导致后续拷贝到子线程的上下文都为 null,同样产生丢失上下文的问题。
以上结论不保证十分准确。
但有下面的测试实验结论:
// 1. parallelStream().map + sqlPreValueLocal = new InheritableThreadLocal<>();
// 很容易出现: No value specified for parameter 1
// 2. parallelStream().map + sqlPreValueLocal = new ThreadLocal<>();
// 不会出现: No value specified for parameter 1
// 2.5 stream().map + sqlPreValueLocal = new ThreadLocal<>();
// 不会出现: No value specified for parameter 1
// 1.5 stream().map + sqlPreValueLocal = new InheritableThreadLocal<>();
// 不会出现: No value specified for parameter 1
// 结论:只有1. parallelStream().map + InheritableThreadLocal 才会现现 No value specified for parameter 1
测试代码:
import java.util.List;
import java.util.stream.Collectors;import org.teasoft.bee.osql.Op;
import org.teasoft.bee.osql.api.SuidRich;
import org.teasoft.honey.osql.core.ConditionImpl;
import org.teasoft.honey.osql.shortcut.BF;//parallelStream().map并行流测ORM
public class StreamSelectTest3 {public static void main(String[] args) {List<Org> orgs00 = getSuidRich().select(new Org()); //约50条记录// 1. parallelStream().map + sqlPreValueLocal = new InheritableThreadLocal<>();
// 很容易出现: No value specified for parameter 1// 2. parallelStream().map + sqlPreValueLocal = new ThreadLocal<>();
// 不会出现: No value specified for parameter 1// 2.5 stream().map + sqlPreValueLocal = new ThreadLocal<>();
// 不会出现: No value specified for parameter 1// 1.5 stream().map + sqlPreValueLocal = new InheritableThreadLocal<>();
// 不会出现: No value specified for parameter 1// 结论:只有1. parallelStream().map + InheritableThreadLocal 才会现现 No value specified for parameter 1// 直接在map中进行数据库查询
// List<Org> orgs = orgs00.stream()List<Org> orgs = orgs00.parallelStream() // 这个才会.map(org -> {// 从数据库中获取 Org 对象的操作// 这里可以是实际的数据库查询操作ConditionImpl cmd = new ConditionImpl();cmd.op("orgName", Op.eq, org.getOrgName());System.out.println("-----------------111111111111111111111111-");List<Org> select1 = getSuidRich().select(new Org(), cmd);return new Org(org.getOrgName());}).collect(Collectors.toList());orgs.forEach(org -> System.out.println("Org name: " + org.getOrgName()));}static SuidRich getSuidRich() {return BF.getSuidRich();}
}
多线程测试测没有发现相应问题。
import java.util.List;import org.teasoft.bee.osql.api.SuidRich;
import org.teasoft.honey.osql.shortcut.BF;public class ThreadSelectTest2 extends Thread{// static SuidRich suidRich=BF.getSuidRich();public static void main(String[] args) throws Exception{ThreadSelectTest2 test[]=new ThreadSelectTest2[5];for (int i = 0; i < test.length; i++) {test[i]=new ThreadSelectTest2();test[i].start();}System.out.println("finished!");}// sqlPreValueLocal = new InheritableThreadLocal<>(); //没问题 , 没那么容易连不上
// sqlPreValueLocal = new ThreadLocal<>(); // 很容易连不上; 但没碰到 No value specified for parameter 1
// org.teasoft.bee.osql.BeeSQLException: The driver was unable to create a connection due to an inability to establish the client portion of a socket.
// This is usually caused by a limit on the number of sockets imposed by the operating system. This limit is usually configurable.
// For Unix-based platforms, see the manual page for the 'ulimit' command. Kernel or system reconfiguration may also be required.public void run() {SuidRich suidRich=BF.getSuidRich();List<Org> listOrg=suidRich.select(new Org()); //约50条for (int i = 0; i < 2; i++) {for (int j = 0; j < listOrg.size(); j++) {Org org = new Org(listOrg.get(i).getOrgName()); //拿外层每一条的值 又去查一遍;只是测试性能,不考虑业务正确与否suidRich.select(org);}}}}
相关文章:
Java并行流parallelStream()下InheritableThreadLocal引起的问题
Java并行流parallelStream()下InheritableThreadLocal引起的问题 引起问题的代码。 List orgs00 Arrays.asList(new Org("aaa"),new Org("bbb"),new Org("aa0"));List orgs orgs00.parallelStream() .map(org -> {// 模拟从数据库中获取 …...
【C++期末编程题题库】代码+详解18道
适合期末复习c看,或者刚入门c的小白看,有的题会补充知识点,期末复习题的代码一般比较简单,所以语法上没那么严谨。本文所有题目要求全在代码块的最上面。 目录 1、设计复数类 2、设计Computer类 3、实现相加的函数模板 4、圆类…...
一种DevOpts的实现方式:基于gitlab的CICD(一)
写在之前 笔者最近准备开始入坑CNCF毕业的开源项目,看到其中有一组开源项目的分类就是DevOpts。这个领域内比较出名的项目是Argocd,Argo CD 是一个用于 Kubernetes 的持续交付 (Continuous Delivery) 工具,它以声明式的方式实现了应用程序的…...
nodejs和vuejs的区别
一、vue项目开发中,两个经常混合使用。 不同: 1、概念不同: 一个是前端框架,一个是服务端语言。 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使…...
16、Kubernetes核心技术 - 节点选择器、亲和和反亲和
目录 一、概述 二、节点名称 - nodeName 二、节点选择器 - nodeSelector 三、节点亲和性和反亲和性 3.1、亲和性和反亲和性 3.2、节点硬亲和性 3.3、节点软亲和性 3.4、节点反亲和性 3.5、注意点 四、Pod亲和性和反亲和性 4.1、亲和性和反亲和性 4.2、Pod亲和性/反…...
面试算法96:字符串交织
题目 输入3个字符串s1、s2和s3,请判断字符串s3能不能由字符串s1和s2交织而成,即字符串s3的所有字符都是字符串s1或s2中的字符,字符串s1和s2中的字符都将出现在字符串s3中且相对位置不变。例如,字符串"aadbbcbcac"可以由…...
什么是Vue.js的响应式系统(reactivity system)?如何实现数据的双向绑定?
Vue.js的响应式系统是指一种能够跟踪数据变化并实时更新相关界面的机制。它是Vue.js框架的核心特性之一。 在Vue.js中,你可以使用数据绑定语法将数据绑定到DOM元素上。当绑定的数据发生变化时,Vue.js会自动监听这些变化并更新相关的DOM元素。 Vue.js实…...
力扣labuladong一刷day52天LRU算法
力扣labuladong一刷day52天LRU算法 文章目录 力扣labuladong一刷day52天LRU算法概念一、146. LRU 缓存思路一:使用双向链表加map来手动实现。思路二:使用LinkedHashMap 概念 LRU的全称为Least Recently Used,翻译出来就是最近最少使用的意思…...
CCNP课程实验-06-EIGRP-Trouble-Shooting
目录 实验条件网络拓朴 环境配置开始排错错误1:没有配置IP地址,IP地址宣告有误错误2:R3配置了与R1不同的K值报错了。错误3:R4上的AS号配置错,不是1234错误4:R2上配置的Key-chain的R4上配置的Key-chain不一致…...
判断完全数-第11届蓝桥杯省赛Python真题精选
[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第27讲。 判断完全数&#…...
【Bootstrap5学习 day12】
Bootstrap5 导航 Bootstrap5提供了一种简单快捷的方法来创建基本导航,它提供了非常灵活和优雅的选项卡和Pills等组件。Bootstrap5的所有导航组件,包括选项卡和Pillss,都通过基本的.nav类共享相同的基本标记和样式。 创建基本导航 要创建简单…...
算法训练第五十九天|503. 下一个更大元素 II、42. 接雨水
503. 下一个更大元素 II: 题目链接 给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之…...
mysql之数据类型、建表以及约束
目录 一. CRUD 1.1 什么是crud 1.2 select(查询) 1.3 INSERT(新增) 1.4 UPDATE(修改) 1.5 DELETE(删除) 二. 函数 2.1 常见函数 2.2 流程控制函数 2.3聚合函数 三. union与union all 3.1 union 3.2 union all 3.3 具体不同 3.4 结论 四、思维导图 一. CRUD 1.1…...
复试 || 就业day04(2024.01.05)项目一
文章目录 前言线性回归房价预测加载数据数据查看数据拆分数据建模模型的验证、应用模型的评估 总结 前言 💫你好,我是辰chen,本文旨在准备考研复试或就业 💫本文内容来自某机构网课,是我为复试准备的第一个项目 &#…...
华为机试真题实战应用【赛题代码篇】-最小传输时延(附python、C++和JAVA代码实现)
目录 问题描述 输入描述: 输出描述: 知识储备 解题思路 思路一...
C++ 运算符重载
(Operator) 加分 减法 []的重载 #include <iostream> using namespace std;class time1 {public:time1(){shi0;fen0;miao0;}time1(int shi, int fen, int miao){this->shi shi;this->fen fen;this->miao miao;}time1 operator (ti…...
vue3学习 【2】vite起步和开发工具基本配置
vite的简介 官方文档 刚起步学习,所以我们只需要按照官方文档的入门流程即可。推荐阅读一下官网的为什么使用vite vite目前需要的node版本是18,可以参考上一篇文章的安装nvm,用来进行多版本的node管理。 vite安装与使用 npm create vitela…...
计算机创新协会冬令营——暴力枚举题目06
我给大家第一阶段的最后一道题就到这里了,下次得过段时间了。所以这道题简单一点。但是足够经典 下述题目描述和示例均来自力扣:两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target …...
单片机快速入门
参考连接: 安装MinGW-64(在win10上搭建C/C开发环境)https://zhuanlan.zhihu.com/p/85429160MinGW-64; 链接:https://pan.baidu.com/s/1oE1FmjyK7aJPnDC8vASmCg?pwdy1mz 提取码:y1mz --来自百度网盘超级会员V7的分享C…...
Eureka相关问题及答案(2024)
1、什么是Eureka? Eureka是一个由Netflix开发的服务发现(Service Discovery)工具,它是Spring Cloud生态系统中的一个关键组件。服务发现是微服务架构中的一个重要概念,它允许服务实例在启动时注册自己,以便…...
2026年10款降AI率网站横评:最高AI率100%直降至0.12%
2026年全球学术界对AIGC内容的监管持续收紧,论文查重与AI痕迹检测标准迎来全面升级,高校及科研机构纷纷引入更精准的检测系统,导致学术不端行为面临更严苛的审查。在此背景下,论文降AI工具市场需求激增,用户规模在半年…...
CDCS金融算法挑战赛终极指南:甜橙金融与融360实战案例深度解析
CDCS金融算法挑战赛终极指南:甜橙金融与融360实战案例深度解析 【免费下载链接】CDCS Chinese Data Competitions Solutions 项目地址: https://gitcode.com/gh_mirrors/cd/CDCS CDCS(Chinese Data Competitions Solutions)是中国数据…...
百度网盘全自动化实录:Hermes Agent + bb-browser
缘起:今天风暴了一下,准备实践一下Hermes自动售卖数字产品实现自动变现的MVP,谁知道刚开始就卡在了操作百度网盘,要么被反爬,要么靠之前开发的computer use for win截图点坐标像瞎子摸象。最后换了条路——用 bb-brows…...
2026这6款硬核降AIGC软件大公开,一键把AI检测率精准控到安全区!
步入 2026 年,学术圈的规则早已不是过去那个模样。从最初的查重率焦虑,到如今的 AIGC 检测风暴,整个环境正在经历一场前所未有的洗牌。AI 检测系统越来越“狡猾”,高校的审查标准也愈发严苛。光是把重复率压下去已经不够了&#x…...
企业内训系统集成AI问答时采用Taotoken的成本控制实践
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 企业内训系统集成AI问答时采用Taotoken的成本控制实践 应用场景类,设想一个企业开发内训知识库系统的场景,…...
实测Taotoken在多模型调用下的延迟与稳定性体感
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 实测Taotoken在多模型调用下的延迟与稳定性体感 1. 引言 在集成多个大模型API到实际业务或开发工作流时,开发者通常需…...
BMS工程师必看:用南京集澈DVC1006做外部被动均衡,这几点时序和奇偶机制千万别搞错
BMS工程师实战指南:DVC1006被动均衡设计的五大关键陷阱与解决方案 在新能源汽车和储能系统井喷式发展的今天,电池管理系统(BMS)的可靠性直接决定了整个电池包的安全边界。作为国内AFE芯片的标杆产品,南京集澈DVC1006凭借其高集成度与稳定性&…...
Python 3.x 下修复MD5编码报错:手把手教你搞定BUUCTF那道‘丢失的MD5’题
Python 3.x下MD5编码报错全解析:从CTF实战到通用解决方案 当你在BUUCTF中遇到那道关于"丢失的MD5"的题目时,是否也曾被那个看似简单的编码错误困扰?这不仅仅是一道CTF题目的解法,更是Python 3.x版本中字符串处理机制变…...
ElevenLabs湖北话语音合成:从零部署到商用级TTS的7大避坑步骤(附武汉/宜昌/襄阳三方言测试数据)
更多请点击: https://kaifayun.com 第一章:ElevenLabs湖北话语音合成的技术定位与方言价值 ElevenLabs 作为全球领先的AI语音生成平台,其核心能力聚焦于高保真、情感化、多语言的文本到语音(TTS)合成。尽管官方尚未正…...
虚实融合新纪元:UWB物理锚点 vs 镜像视界数维空间无感定位
虚实融合新纪元:UWB物理锚点 vs 镜像视界数维空间无感定位虚实融合产业正从“物理锚点绑定”迈向“数维空间原生映射”新纪元。UWB以基站与标签构建刚性物理坐标体系,是虚实同步的硬件依赖范式;镜像视界浙江科技有限公司以纯视觉AI重构空间感…...
