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

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不会, 可以解释为什么吗?

在并行流场景下,使用InheritableThreadLocalThreadLocal可能会出现不同的行为,导致上下文丢失的问题。下面我会解释一下为什么语句1有时会出现上下文丢失,而语句2不会。

  1. 使用InheritableThreadLocal(语句1):

InheritableThreadLocal会使子线程继承父线程中的ThreadLocal变量的值。在并行流中,由于线程池的调度机制,父线程有可能会参与到并行流线程池的调度。如果父线程的上下文在某个时刻被清理,那么后续拷贝到子线程的上下文可能为空,导致上下文丢失的问题。这种情况可能会导致语句1有时会出现上下文丢失的情况。

  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看&#xff0c;或者刚入门c的小白看&#xff0c;有的题会补充知识点&#xff0c;期末复习题的代码一般比较简单&#xff0c;所以语法上没那么严谨。本文所有题目要求全在代码块的最上面。 目录 1、设计复数类 2、设计Computer类 3、实现相加的函数模板 4、圆类…...

一种DevOpts的实现方式:基于gitlab的CICD(一)

写在之前 笔者最近准备开始入坑CNCF毕业的开源项目&#xff0c;看到其中有一组开源项目的分类就是DevOpts。这个领域内比较出名的项目是Argocd&#xff0c;Argo CD 是一个用于 Kubernetes 的持续交付 (Continuous Delivery) 工具&#xff0c;它以声明式的方式实现了应用程序的…...

nodejs和vuejs的区别

一、vue项目开发中&#xff0c;两个经常混合使用。 不同&#xff1a; 1、概念不同&#xff1a; 一个是前端框架&#xff0c;一个是服务端语言。 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型&#xff0c;使…...

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&#xff0c;请判断字符串s3能不能由字符串s1和s2交织而成&#xff0c;即字符串s3的所有字符都是字符串s1或s2中的字符&#xff0c;字符串s1和s2中的字符都将出现在字符串s3中且相对位置不变。例如&#xff0c;字符串"aadbbcbcac"可以由…...

什么是Vue.js的响应式系统(reactivity system)?如何实现数据的双向绑定?

Vue.js的响应式系统是指一种能够跟踪数据变化并实时更新相关界面的机制。它是Vue.js框架的核心特性之一。 在Vue.js中&#xff0c;你可以使用数据绑定语法将数据绑定到DOM元素上。当绑定的数据发生变化时&#xff0c;Vue.js会自动监听这些变化并更新相关的DOM元素。 Vue.js实…...

力扣labuladong一刷day52天LRU算法

力扣labuladong一刷day52天LRU算法 文章目录 力扣labuladong一刷day52天LRU算法概念一、146. LRU 缓存思路一&#xff1a;使用双向链表加map来手动实现。思路二&#xff1a;使用LinkedHashMap 概念 LRU的全称为Least Recently Used&#xff0c;翻译出来就是最近最少使用的意思…...

CCNP课程实验-06-EIGRP-Trouble-Shooting

目录 实验条件网络拓朴 环境配置开始排错错误1&#xff1a;没有配置IP地址&#xff0c;IP地址宣告有误错误2&#xff1a;R3配置了与R1不同的K值报错了。错误3&#xff1a;R4上的AS号配置错&#xff0c;不是1234错误4&#xff1a;R2上配置的Key-chain的R4上配置的Key-chain不一致…...

判断完全数-第11届蓝桥杯省赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第27讲。 判断完全数&#…...

【Bootstrap5学习 day12】

Bootstrap5 导航 Bootstrap5提供了一种简单快捷的方法来创建基本导航&#xff0c;它提供了非常灵活和优雅的选项卡和Pills等组件。Bootstrap5的所有导航组件&#xff0c;包括选项卡和Pillss&#xff0c;都通过基本的.nav类共享相同的基本标记和样式。 创建基本导航 要创建简单…...

算法训练第五十九天|503. 下一个更大元素 II、42. 接雨水

503. 下一个更大元素 II&#xff1a; 题目链接 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序&#xff0c;这个数字之…...

mysql之数据类型、建表以及约束

目录 一. CRUD 1.1 什么是crud 1.2 select(查询) 1.3 INSERT(新增) 1.4 UPDATE(修改&#xff09; 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)项目一

文章目录 前言线性回归房价预测加载数据数据查看数据拆分数据建模模型的验证、应用模型的评估 总结 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;本文内容来自某机构网课&#xff0c;是我为复试准备的第一个项目 &#…...

华为机试真题实战应用【赛题代码篇】-最小传输时延(附python、C++和JAVA代码实现)

目录 问题描述 输入描述: 输出描述: 知识储备 解题思路 思路一...

C++ 运算符重载

&#xff08;Operator&#xff09; 加分 减法 []的重载 #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的简介 官方文档 刚起步学习&#xff0c;所以我们只需要按照官方文档的入门流程即可。推荐阅读一下官网的为什么使用vite vite目前需要的node版本是18&#xff0c;可以参考上一篇文章的安装nvm&#xff0c;用来进行多版本的node管理。 vite安装与使用 npm create vitela…...

计算机创新协会冬令营——暴力枚举题目06

我给大家第一阶段的最后一道题就到这里了&#xff0c;下次得过段时间了。所以这道题简单一点。但是足够经典 下述题目描述和示例均来自力扣&#xff1a;两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target …...

单片机快速入门

参考连接&#xff1a; 安装MinGW-64&#xff08;在win10上搭建C/C开发环境&#xff09;https://zhuanlan.zhihu.com/p/85429160MinGW-64; 链接&#xff1a;https://pan.baidu.com/s/1oE1FmjyK7aJPnDC8vASmCg?pwdy1mz 提取码&#xff1a;y1mz --来自百度网盘超级会员V7的分享C…...

Eureka相关问题及答案(2024)

1、什么是Eureka&#xff1f; Eureka是一个由Netflix开发的服务发现&#xff08;Service Discovery&#xff09;工具&#xff0c;它是Spring Cloud生态系统中的一个关键组件。服务发现是微服务架构中的一个重要概念&#xff0c;它允许服务实例在启动时注册自己&#xff0c;以便…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...

精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑

精益数据分析&#xff08;98/126&#xff09;&#xff1a;电商转化率优化与网站性能的底层逻辑 在电子商务领域&#xff0c;转化率与网站性能是决定商业成败的核心指标。今天&#xff0c;我们将深入解析不同类型电商平台的转化率基准&#xff0c;探讨页面加载速度对用户行为的…...

基于 HTTP 的单向流式通信协议SSE详解

SSE&#xff08;Server-Sent Events&#xff09;详解 &#x1f9e0; 什么是 SSE&#xff1f; SSE&#xff08;Server-Sent Events&#xff09; 是 HTML5 标准中定义的一种通信机制&#xff0c;它允许服务器主动将事件推送给客户端&#xff08;浏览器&#xff09;。与传统的 H…...