Spring 异步线程中传递ThreadLocal

使用Async如何传递ThreadLocal及自定义线程池 1. 当使用ThreadLocal存储数据时,程序中使用了@Async异步任务注解,后导致子任务中无法获取到ThreadLocal存储的数据2. 使用@Async注解后默认的线程池最大线程数和队列长度为 Integer.MAX_VALUE,当并发量增高后会导致系统负载飙升甚至系统宕机。 阅读详情

上周熬夜查了一个线上问题,最后复盘会议却没有深入,部门里还是要求快,根据熵增定律,软件系统需要定期注入能力,以维持系统稳定,如果只求快,那么就是牺牲系统的扩展性、健壮性、稳定性。

后期总结一篇生产环境排查问题指南。

今天主体是一个补丁,设计dubbo 超时,spring 异步方法,spring 异步线程传递ThreadLocal 信息。

一、dubbo 超时怎样

{"code":"9","msg":"服务方法(xxx.xxx.xxx:1.0)业务逻辑出错","body":"java.lang.RuntimeException: com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method execute in the service com.fancv.xxx.ccc.client.DamClient. Tried 1 times of the providers [101.51.21.415:30001] (1/1) from the registry zoo1.wwww.cc:30002 on the consumer 12.50.12.148 using the dubbo version 2.5.3. Last error is: Invoke remote method timeout. method: execute, provider: dubbo://10.50.2.145:30001/com.fancv.xxx.ccc.client.DamClient?anyhost=true&application=fancv-wede-sop&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&group=dubbo&interface=com.fancv.xxx.ccc.client.DamClient&metadata-type=remote&methods=execute&pid=411&pln=fancv-main-sop-gray&protocol=dubbo&release=2.7.7&retries=-1&revision=1.0.0.gray-SNAPSHOT&side=consumer&timeout=5000&timestamp=1640324905371&version=1.0.0-gray, cause: Waiting server-side response timeout by scan timer. start time: 2021-12-27 18:30:28.986, end time: 2021-12-27 18:30:34.018, client elapsed: 0 ms, server elapsed: 5032 ms, timeout: 5000 ms, request: Request [id=180989, version=2.0.0, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=execute, parameterTypes=[class com.fancv.www.sdk.api.RopRequest], 

报错日志显示 dubbo 服务调用超时,测试反馈页面报错,但是程序逻辑执行成功了。

二、 改进方法

spring 异步调用,一般情况下能利用成熟框架的功能就不要自己造轮子,这里采用spring的 @Async 注解

使用方法自行研究

参考 https://www.jianshu.com/p/2d4b89c7a3f1

三、改进中遇到的问题

发现整个文件复制的业务逻辑流程需要用户的登录状态,显而易见,大多数系统会把用户的登录状态放入在Context 中,使用ThreadLocal 的方式进行传递,那么起了一个异步线程之后,登录信息如果不做任何处理就消失了,程序报错。

1.方法传递,把用户信息当做一个参数 传递的新的线程

简单,容易理解

2.很多场景需要异步调用,那么可以使用一个自定义的注解

拦截件处理加了注解的方法,增加ThreadLocal的传递过程。

或许不就的将来spring 框架会支持。

Spring Boot异步任务里Request对象突然‘消失’?一个参数解决RequestContextHolder.getRequestAttributes()为null 本文深入解析了Spring Boot异步任务中Request对象丢失的问题,揭示了ThreadLocal与请求上下文的关系,并提供了通过`inheritRequestAttributes`参数传递Request对象的解决方案。文章详细对比了多种方案的优缺点,并给出了高级场景处理、性能优化及安全考量的实用建议,帮助开发者高效解决异步请求传递难题。 阅读详情

相关推荐

智能座舱架构与芯片- (9) 音频篇 上

从A2B收发器衍生出来的简化产品具备各种级别的功能,例如端点从节点(不支持TDM)、简化型主节点(支持较短的电缆和更少的从节点数量),以及简化型端点从节点(支持较短电缆和更少的PDM输入)。例如,AVB中的talker和listener是不同的设备,它们的参考时钟源可能并不相同。传统的车载收音机通过天线接收无线电信号,然后由调谐模块(Tuner)进行信号调谐,信道过滤,信道均衡,多路改善,信号解调等,转为数字信号后再交给DSP进行立体声解码,噪声抑制,弱信号处理,最后从车载音响系统进行播放。

joanna_xiao的博客 4907

Spring异步任务中如何用TaskDecorator安全传递线程上下文(附完整代码示例)

本文深入探讨了在Spring异步编程中,如何利用TaskDecorator接口安全、优雅地传递线程上下文信息,解决用户身份、Trace ID等关键数据在异步任务中丢失的问题。通过完整的代码示例,详细展示了从定义上下文模型、实现MdcTaskDecorator到集成Spring线程池的完整生产级解决方案,确保异步任务的可观测性与数据一致性。

weixin_29273849的博客 295

2026 具身智能 VLA/WAM 全栈学习与训练路线:从动作建模、SFT、RL 到世界模型的 RTX PRO 6000 96GB 单卡实战指南

我会把这张表做成“”而不是只列论文名:先核对每个模型截至的公开代码、训练目标和数据接口,再单独给你一套。对于没有公开、只有推理代码或训练细节不完整的模型,我会明确标出来,避免把“论文里提到”误写成“可复现”。目前有一个重要更新:。截至今天 NVIDIA 官方开源主线已经是换成 Cosmos-Reason2-2B/Qwen3-VL 架构,动作端仍是连续路线,而且官方明确给出单卡微调时默认只训练,峰值显存约。所以你的 96GB 单卡对 GR00T SFT 非常宽裕。可以。下面我按,把它整理成一张真正面向“

u013250861的博客 446

异步线程中如何传递threadlocal中的信息

springboot+线程池

yeluowan的博客 2408

【AWS】创建aws云服务器EC2实例

本文介绍了如何创建aws的EC2云服务器,并介绍了如何使用Xshell远程连接上云服务器

Marcos921的博客 2501

STM32+OOK通讯(OOK发送+OOK接收)+cubemx配置

关于OOK通信,我的理解就是将要发送的信息转换成高低电平(即0和1),然后接收方通过对01进行解码获得信息。于是我用了非常朴素的字符串转二进制+AM调制来完成通信链。话不多说我们直接开始!!!

qq_73856732的博客 2340

实现ThreadLocal在异步线程(包括线程池)中传递

JDK提供了本地线程共享的ThreadLocal和在创建线程时可继承的InheritableThreadLocal,但是由于大多数情况都推荐使用线程池来进行异步处理,InheritableThreadLocal就达不到我们的预期。但是可以参考它的实现思路,在进行线程间的传递时(如创建线程或创建Runnable实现类),将与父线程绑定的ThreadLocal值传递给子线程,就可实现父子线程ThreadLocal的传递。

avatar6780的博客 5411

在Simulink中实现基于深度强化学习的控制算法仿真建模

通过上述步骤,你可以在Simulink中实现基于深度强化学习的控制算法仿真建模。这种方法适用于许多复杂的控制问题,尤其是当传统控制方法难以找到有效解决方案时。随着经验的积累,你可以进一步探索不同的深度强化学习算法及其变种,以适应更广泛的应用场景。此外,还可以结合其他先进技术(如迁移学习、多智能体协作等),提升模型的表现能力。

amy_mhd的博客 415

Spring Boot 异步线程间数据传递ThreadLocal

Spring Boot 异步线程间数据传递ThreadLocal

zhk 812

YOLOv8-COCO指标转换

本文介绍了将YOLO格式数据集转换为COCO格式并评估模型性能的完整流程。首先需将YOLO格式的标注数据转换为COCO格式,通过修改classes、image_path等参数适配不同数据集。然后使用YOLO模型对验证集进行预测并保存结果为JSON格式。最后通过比较预测结果和转换后的COCO标注文件,使用COCO官方评估指标和TIDE工具进行性能分析,生成包含AP、AR等指标的报告及错误分析图表。整个过程实现了从数据准备到模型评估的完整闭环,为计算机视觉任务提供标准化的性能评估方案。

FJN110的博客 403

Vue - 列表拖曳排序 / 鼠标拖动改变顺序排列高效简洁组件(支持PC端与移动端触屏拖动,也可在滚动条内排序自动滚动,流畅丝滑无 BUG)

Vue-高效简洁列表拖曳排序/鼠标拖动改变顺序排列组件支持PC端与移动端触屏拖动,也可在滚动条内排序自动滚动,流畅丝滑无BUG列表拖曳排序插件vuedraggable拉动拽动拖动顺序改变排序js,vue.js,nuxt.js列表如何实现鼠标拖曳改变顺序排列支持滚动条内复杂数据对象带拖动效果动画排序完毕自动排列数组位置克隆Vue.Draggable官方文档教程SortableJS与vuedraggable列表拖动排序Vue拖拽组件库vuedraggable的安装与使用用户用鼠标拖动排序功能源码最好

🏆 前端领域优质创作者 4848

多线程系列-ThreadLocal

线程安全-ThreadLocal 前言 共享资源被多个线程同时访问可能出现不安全的事情。线程安全一直是很重要的事情,没处理好线程安全的问题可能导致错误甚至很难复现排查。 常见的解决办法有定义不可变(immutable)变量:例如Java中的String类型、Guava库里的ImmutableCollections。还有就是对访问共享资源的线程加上锁:例如JUC包下的ReentrantLock和JDK自带的synchronized关键字,或者借助Unsafe类来实现的自旋锁。还有一种是保证所有执行的任务都一个

ahao' Blog 1715

LDRA Testbed(TBrun)软件单元测试_实例讲解(对多次调用的函数打桩)

在之前的文章《LDRA Testbed(TBrun)软件单元测试_操作指南》中,已经讲解了如何使用TBrun进行软件单元测试的基本操作步骤。本篇文章将结合实例进一步讲解被测函数中包含多次调用其他函数时,如何对其打桩来实现测试目的(详细的操作流程本文不再重述,若有不清楚的,可以结合之前的操作指南一起来看)。本文以一个被测函数作为示例,讲解了如何使用Testbed(TBrun)对涉及到多次调用其他函数的被测函数进行单元测试。本文的示例可能比较简单,但是思路、方法和流程都是通用的,希望对大家有所帮助。

文章主要涉及嵌入式软件开发、测试、项目管理等,欢迎交流,共同进步。 1462

spring boot 异步线程@Async 传递 threadLocal数据

第一步在启动服务加上 @EnableAsync 注解。第三步,增加 线程池。提供给 @Async 用。第二步:导入阿里 线程工具类。@Async 的使用。

zhanglinlang的专栏 402

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

聊聊reactor异步线程的变量传递

本文主要研究下reactor异步线程的变量传递。

liuhyusb的博客 641

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

解决 Spring Security 在异步线程中用户信息丢失的问题

Spring Security 在异步线程中丢失用户信息是一个常见但容易解决的问题。简单项目:使用方案1(手动传递)即可中型项目:建议使用方案2(自定义线程池)大型项目:推荐使用方案3(Spring Security官方方案)或综合方案性能敏感:考虑方案4(避免在异步中使用安全上下文)无论选择哪种方案,都要记住:始终在finally块中清理安全上下文合理配置线程池参数添加适当的监控和日志进行充分的测试。

Vic10101的博客 918

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

ThreadLocal常见使用场景

threadLocal常见常见,面试可用!

自救 唯有自强 819

ThreadLocal 上下文

是线程本地存储的工具,核心价值是线程数据隔离。适用场景:线程不安全工具类封装、上下文信息传递。用完即清(remove(),否则可能导致内存泄漏或脏数据。理解的核心是抓住 “线程私有副本” 这一特性,同时注意其在长期存活线程(如线程池)中的使用风险。ThreadLocal 如果想异步,如何实现在异步场景中,由于是与当前线程绑定的,而异步任务会在新线程中执行,直接使用会导致上下文丢失。要实现异步场景下的上下文传递,核心思路是。

学长的猫的博客 508

为什么 @Async 方法中无法使用 ThreadLocal?

摘要: @Async方法因切换线程无法访问原线程的ThreadLocal数据(如用户ID)。解决方案是显式传递参数:将所需数据(单个字段或封装为上下文对象)通过方法参数传入。虽然可通过InheritableThreadLocal自动传递,但推荐参数传递以确保线程安全。核心原则:异步方法需独立获取上下文,避免隐式依赖线程局部变量。

qq_61723836的博客 295

如何在子线程和线程池中使用 ThreadLocal 传输上下文

Java技术架构 2019-01-16 12:17:28 专注于Java领域优质技术号,欢迎关注 作者:晓_魂淡 问题举例 在 Spring 框架中,使用 @Async 注解时,如何获取 ThreadLocal 中的数据? 使用 CompletableFuture.supplyAsync 处理异步中,supplyAsync执行的方法如何获取 ThreadLocal 中的数据? Ex...

u011277123的博客 3955

为什么响应式编程无法从Threadlocal里获取数据?

响应式编程模型(如 Spring WebFlux)和传统的 Servlet 基于线程的模型(如 Spring MVC)在处理请求的方式上有显著不同。在传统的 Spring MVC 应用中,每个请求都是由一个固定的线程处理的,因此可以便利地使用。然而,在响应式编程模型中,因为处理流程可能在多个线程之间切换,所以无法保证整个请求处理链在同一个线程中执行。是跟随响应式流的,并且可以在响应式链中的不同操作和不同线程间保持数据的连贯性。的数据是绑定到特定线程的,当请求处理跳转到新的线程时,原线程的。

主要作为个人的笔记用,Not For Everyone。 956

spring异步线程传递线程上下文

我们直接使用@Async注解,当然你也可以直接使用线程池,效果是一样的 首先我们创建ContextDecorator实现TaskDecorator接口 package com.qimo.omsa.demo.thread; import java.util.Map; import org.springframework.core.task.TaskDecorator; /** * @Description TODO * @Author 姚仲杰#80998699 * @Date 2022/1/30 1

a807719447的专栏 1577

Springcloud 自定义线程池

ThreadConfig.java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.ExecutorService; import java.util.concur...

zhaoyang10的专栏 2898

java多线程造成数据丢失_详解Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失...

在Spring Cloud中我们用Hystrix来实现断路器,Zuul中默认是用信号量(Hystrix默认是线程)来进行隔离的,我们可以通过配置使用线程方式隔离。在使用线程隔离的时候,有个问题是必须要解决的,那就是在某些业务场景下通过ThreadLocal来在线程里传递数据,用信号量是没问题的,从请求进来,但后续的流程都是通一个线程。当隔离模式为线程时,Hystrix会将请求放入Hystrix的线...

weixin_39827034的博客 1827

解决异步任务无法获取到Token中的用户信息问题

Spring Security的SecurityContext基于ThreadLocal实现,异步任务在新线程执行时无法直接获取用户认证信息。解决方法包括:1)手动传递SecurityContext并在任务结束后清除;2)直接传递用户ID等具体信息;3)使用TaskDecorator自动传递上下文。核心是确保上下文正确传递,并在任务完成后及时清理,避免内存泄漏和权限污染。三种方法各有利弊,可根据实际场景选择最合适的方案。

qq_45480682的博客 352
上一篇: mac Gradle idea中启动单元测试
下一篇: 程序员面试系列(1)一名 java面试官内心独白
hamish-wu
博客等级 码龄15年 2814粉丝 162原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值