【ThreadLocal】单线程反射方法传参使用ThreadLocal

Java线程安全三要素:原子性、可见性、有序性深度解析 线程安全是Java高并发系统的核心基础,本质是保障多线程环境下共享数据的一致性与确定性。其技术原理围绕JVM内存模型(JMM)展开,必须同时满足原子性(操作不可分割)、可见性(修改对其他线程及时生效)和有序性(禁止破坏逻辑的指令重排)三大要素。仅使用synchronized或volatile无法自动达成全部要求——前者不解决无锁场景下的性能瓶颈,后者不保证复合操作原子性。在电商秒杀、库存扣减、缓存更新等典型高并发应用场景中,正确权衡锁粒度、选择ConcurrentHashMap或AtomicInteger等 阅读详情

参考使用ThreadLocal

业务场景

在一个线程中,需要使用反射的方式去调用某个类的方法,如:

String randomStr = "ugefqbfl";
//获取类对象
Class clazz = Class.forName("com.xxx.Test");
//实例化对象
Object o = clazz.newInstance();
//获取想要执行的方法
Method execute = clazz.getDeclaredMethod("execute", String.class);
//执行方法
execute.invoke(o, "param");
//其他操作...
                

如果想把 randomStr 参数传到反射方法中使用,如:

//获取想要执行的方法
Method execute = clazz.getDeclaredMethod("execute", String.class, String.class);
//执行方法
execute.invoke(o, "param", randomStr);

如果是直接传参,通用性不高,随着后续业务的发展可能要传入更多的参数,这样就要一直修改多出,耦合也高。因为反射这些操作我的业务场景都是在一个异步线程中执行,所以我考虑通过 ThreadLocal 来传递参数。

实现方法

  1. 我们先定义一个上下文类,如TaskContext:
public class TaskContext implements AutoCloseable {
    static final ThreadLocal<Map<String, String>> ctx = new ThreadLocal<>();

    public TaskContext(String randomStr) {
        Map<String, String> map = new HashMap<>();
        map.put("randomStr", randomStr);
        ctx.set(map);
    }

    public static String getRandomStr() {
        return ctx.get().get("randomStr");
    }

    @Override
    public void close() {
        ctx.remove();
    }
}

这里实现了一个接口 AutoCloseable 自动关闭,是为了在方法执行完以后,将线程的上下文内容清空。因为一般线程都是在线程池中使用,如果没有清空内容,线程复用的时候会把上次的状态变量带到本次的执行中。

  1. 原来的场景加上上下文
try (TaskContext ctx = new TaskContext()) {
    String randomStr = "ugefqbfl";
    //获取类对象
    Class clazz = Class.forName("com.xxx.Test");
    //实例化对象
    Object o = clazz.newInstance();
    //获取想要执行的方法
    Method execute = clazz.getDeclaredMethod("execute", String.class);
    //执行方法
    execute.invoke(o, "param");
    //其他操作...
}

在 try() 中实例化 TaskContext ,会在方法执行完成后自动调用实现 AutoCloseable 接口的 close() 方法,不管你有没有声明 finally 。

  1. 反射方法中使用
public class Test {
    public void execute(String param) {
       String randomStr = TaskContext.getRandomStr();
       ...
    }
}

可以直接通过 TaskContext 的静态方法获取到 randomStr 参数。

以上,这样就完成了单线程内的反射方法传参。

Java字符串三剑客:String、StringBuilder、StringBuffer原理与实战选型 字符串拼接是Java基础开发中最常见也最易出错的操作之一,其性能瓶颈往往源于内存分配策略与对象生命周期管理。理解String的不可变性设计、StringBuilder的无锁高效拼接、StringBuffer的同步机制,本质是掌握JVM字符串常量池、堆内存布局及字节码生成逻辑。从编译期优化(如+号转StringBuilder)到运行时扩容(newCapacity = old*2+1),再到线程安全模型(synchronized粒度与ThreadLocal替代),技术价值体现在GC压力降低、CPU利用率优化和响 阅读详情

相关推荐

Java,反射的用法,getDeclaredMethods与getMethods 的区别

/** * Title: Food * Description: * @date 2018/1/6 13:49 */ public interface Food { public void interfaceGetColor(); } /** * Title: Animal * Description: * @date 2018/1/6 13:48 */ public ...

Top5软件工程硕士,先后在京东、字节从事多年Java后端开发、实时和离线大数据开发 1717

反射的使用!!!

应用场景:MyBatis拦截器处理参数时使用,在做商城项目时,我们的数据表中都有lastUpdatBy这个字段,我们绝大多数业务都需要对lastUpdateBy进行赋值,所以我们就在Mybatis拦截器中通过反射获取参数,然后通过ThreadLocal中的localuser进行统一对其赋值。

qq_64847107的博客 243

别再只飞不记了!用CsvView分析你的大疆飞行日志,优化航拍与排查炸机原因

本文详细介绍了如何利用CsvView工具分析大疆无人机的飞行日志,帮助用户优化航拍效率和飞行安全。通过解读飞行日志中的关键数据,如电池性能、飞行轨迹等,用户可以及时发现潜在问题并改进飞行习惯。文章还提供了事故排查方法和进阶分析技巧,适合无人机爱好者和专业飞手。

weixin_42535461的博客 547

反向理解ThreadLocal,或许这样更容易理解

比如一个Spring项目,处理事务也是用的ThreadLocal,Dubbo的RpcContext也是用的ThreadLocal,处理一个请求通常都是在一个线程中去完成的,假设处理一个请求即用到Dubbo发起rpc调用,又用到事务注解操作数据库,那么至少就存在两个ThreadLocal 往一个线程Thread实例的threadLocals字段写数据。创建一个线程都是通过new Thread创建的,使用线程池也不例外,但不代表Thread的字段就是线程安全的,它也是一个普通的对象,也是分配在堆中。

吴就业 310

VirtualLab初学者教程-1.用户界面

目录前言一、VirtualLab Fusion简介1.软件2.内置工具箱:二、用户界面认识1.上方菜单栏2.右侧面主窗口3.底部窗口附 前言 感觉做VirtualLab的资料不是特别多,可能用的朋友也比较少吧,笔者最近也因为大创需要刚刚开始入门,把网上有的英文资料整理了一下,加了一点自己的内容发出来希望帮助更多在学习中的朋友,有用词不当之处还请多多包涵。 一、VirtualLab Fusion简介 因为是第一讲,简单啰嗦一下软件本身,参考官方介绍。 1.软件 VirtualLab是由德国LightTran

ClaireTang1的博客 2万+

lammps案例:热导率模拟案例讲解(NEMD方法)

lammps计算热导率大体可以分为三种方法:EMD、NEMD、rNEMD。 本文介绍非平衡模拟(NEMD)热导率的计算方法。 NEMD下热导率计算公式为: k=dQ*dZ/dt k:热导率 dQ:能量通量。 dT/dZ:温度梯度。 非平衡态下计算热导率的原理是在材料的两端或者中间设置热源和冷源。 在热源输入热量,在冷源抽取等量的热量,在这个过程中计算材料内部会有热量的传递,产生温度梯度。 在lammps模拟中得到能量通量和温度梯度,代入公式即可求得热导率。 热量的输入方式有多种,如fix langevin

lammps_jiayou的博客 1万+

java.lang.Class.getDeclaredMethod()方法详解

java.lang.Class.getDeclaredMethod()方法用法 注:方法返回一个Method对象,它反映此Class对象所表示的类或接口的指定已声明方法。 描述 java.lang.Class.getDeclaredMethod()方法返回一个Method对象,它反映此Class对象所表示的类或接口的指定已声明方法。 name 参数是一个字符串,指定所需

gao_chun 6万+

MongoDB分布式事务实现:两阶段提交、日志复制与冲突解决

MongoDB分布式事务机制解析 本文深入剖析了MongoDB 4.0+版本的分布式事务实现原理,重点分析了其在跨文档/跨集合/跨分片场景下的数据一致性解决方案。核心内容包括: 底层机制:采用改进的两阶段提交协议,通过oplog日志复制实现无中心协调器的事务管理,结合WiredTiger存储引擎和锁机制保障ACID特性。 创新设计:将传统2PC的中心协调功能分散到Primary节点,利用oplog作为事务状态记录,实现自动故障恢复和60秒超时回滚机制。 性能优化:针对大事务、写冲突等常见问题,提出拆分微事务

数据知道的博客 1261

JAVA反射解析-getDeclaredMethod方法

解析反射类java.lang.Class中的属性和方法 1、public Method getDeclaredMethod(String name, Class<?>… parameterTypes) 常用反射获取对象的方法 Class<? extends UserController> clazz = userController.getClass(); //<1>处代码 在获取到Class对象之后,便可以获取有参方法 ① Method method = clazz.

Only_Young的博客 2万+

Experion PKS系列开发:I_O模块_ExperionPKS与第三方I-O模块的集成

通过上述步骤,可以成功将第三方I/O模块集成到Honeywell Experion PKS系统中,实现对现场设备的监视和控制。集成过程中需要注意选择合适的第三方模块,配置正确的通信参数,编写正确的控制逻辑,并进行充分的测试,以确保系统的稳定性和可靠性。不同的通信协议(如Modbus、Profibus、Ethernet/IP、CANopen、OPC UA)有其独特的配置和编程方法,但总体流程相似。在实际应用中,根据项目需求选择合适的协议和模块,可以有效提高系统的灵活性和适应性。

zhubeibei168的博客 1099

ComfyUI 汉化教程(中文界面)

如果你对翻译的结果不满意,还可以进行修改。首先,进入目录,可以看到该目录中有很多 JSON 文件:打开 JSON 文件,找到要修改的内容,修改对应的Value值即可:最后,重启 ComfyUI 即可。

水滴的博客 1万+

JDK 17下ThreadLocal实战:线程隔离、内存泄漏与线程池传参全解析

在Java并发编程中,线程安全问题始终是工程实践的核心挑战。ThreadLocal作为线程局部变量,通过空间换时间策略为每个线程维护独立副本,有效避免共享对象的状态竞争。其底层依赖Thread类内部的ThreadLocalMap,并以弱引用作为键的设计虽巧妙,却可能因强引用值未清理引发内存泄漏,尤其在线程池复用长生命周期线程时风险加剧。围绕线程上下文传递,InheritableThreadLocal仅支持父子线程创建时继承,而线程池场景需借助TransmittableThreadLocal或手动快照恢复。J

weixin_30219613的博客 192

药物吸收仿真软件:Caco-2_(9).Caco-2模型在药物开发中的案例分析

通过以上五个案例,我们可以看到Caco-2模型在药物开发中的重要作用。它不仅能够帮助我们预测药物的肠道吸收情况,还能够用于优化药物配方、评估代谢稳定性、研究药物相互作用以及转运蛋白的影响。这些体外实验和仿真分析的结果为药物的进一步临床研究提供了重要的参考依据,有助于缩短药物开发周期,提高研发效率。

kkchenjj的博客 863

java并发编程笔记

1 基础知识 线程创建关键的三种方式。 实现runnaable的run方法 继承thread类并重写run 方法 使用futuretask方式(callable) 好处: 继承的好处是方便传参,set或者构造。 runnable只能使用主线程的final变量 java不支持多继承,如果继承了thread,就不能继承其他类。 futuretask可以拿到返回结果。 wait wait调用前要获取对象的监视器锁,synchronized(共享变量),或者调用它的方法加synchronized修饰 调用wait只

tianyouououou的博客 335

最适合入门的100个深度学习项目

本专栏整理了《PyTorch深度学习项目实战100例》,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集。

优快云 精品推荐 12万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Java 全新 30 组面试复习对比表格

本文对比分析了Java开发中30组关键技术的差异,涵盖单例模式、IO流、JDK特性、缓存、集合、并发等核心知识点。通过表格形式清晰呈现各组技术的实现原理、性能特点、适用场景及注意事项,如饿汉式与懒汉式单例的线程安全对比、BIO与NIO的线程模型差异、强引用与软引用的GC行为区别等。文章还总结了高频易错点,如BigDecimal的精度问题、递归与循环的性能权衡、动态代理的实现限制等,为开发者提供技术选型参考和最佳实践指导。

devilnumber的博客 213

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【JVM】详细分析JVM内存区域

【JVM】详细分析JVM内存区域(1)准备好Math.java、Math.class和JVM结构图(1.1)认清*.java、*.class和JVM之间的关系(1.2)编写一个简单的Math.java文件(1.3)对Math.java文件进行反编译,得到Math.class文件(1.4)准备一个JVM运行时数据区域图(2)从Math.class开始分析流程(2.1)Math.class进入JVM(...

weixin_44823875的博客 516

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

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

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

Java最高频八股文速通

final 类:String 类被声明为 final,这意味着它不能被继承,从而防止了通过继承改变其行为。final 字段:String 类中的 value 字段是 final 的,这保证了 String 对象在创建后其内部字符数组不会被改变。没有提供修改方法:String 类没有提供任何可以修改其内容的方法。所有对 String 的操作(如拼接、替换等)都会生成一个新的String 对象。

qq_43751506的博客 6395

面试题汇总

高频率面试题

weixin_43766298的博客 868

要复习的那些点

2021年离职计划:30岁之前,还是期望在大厂工作,期望薪资是50万/年、涨幅在30%,工作地点在杭州 时间 动作 2021:02:01 离职原因(利弊权衡): 目前现状: 部门leader 8月份被降级、小组目前业务大部分被拿走 、对目前小组的发展前景不是很看好。 离职好处: 1.工资可以又较大涨幅、寻找有价值业务 2.杭州的话,离黄瀛更近。目前尚不清楚黄瀛是否期望一直在杭州、还是说等关系稳定后可以一起去其他城市打拼。 活水选择:

dainandainan1的博客 1633

面试题kkk

这篇文章摘要主要涵盖了Android开发中的核心知识点和技术难点,包括数据结构、Java与Kotlin语言特性、多线程与并发、内存管理、安卓组件与UI、IPC通信、数据库、多媒体处理、设计模式、性能优化、跨端开发等多个方面。文章详细解析了常见数据结构的使用与实现、JVM机制、内存泄漏分析与解决方案、Activity生命周期、事件分发机制、Handler原理、音视频处理、设计模式应用等核心内容,并提供了实际项目中的技术卡点与解决方案。此外,还涉及了性能优化策略、跨端开发差异、技术方案设计思路以及Git常用命令

mix39的博客 928

知识总结 - 常见问题

1. InnoDB存储引擎,三层B+树,单表能存储多少数据MySQl存储单元为1页,1页为16K,即16384Byte非叶子节点存储单元为主键+指针,大小为8+6=14Byte单页可存储16384/14 ≈ 1170个单元,即可存储1170个子节点每个存储单元可标记1页,则前两层可标记1170x1170页第三层叶子节点存储数据,每条数据约1K,单页则可存储16/1=16个数据三层 B+树,单表可存数据约为1170x1170x16=21902400条数据。

yuyehui的博客 834

Java面试常见八股文

覆盖索引:查询时使用了索引,并且需要返回的列,在该索引中全部能够找到回表:通过非聚簇索引,找到对应的主键id值,再到聚簇索引中,根据主键id查询到叶子结点中存储的整行数据两个或两个以上的线程在执行过程中,因争夺共享资源而造成的一种互相等待的现象死锁的四个条件互斥:共享资源X和Y只能被一个线程占用请求与保持:线程T1已经取得共享资源X,在等待共享资源Y时,不会释放共享资源X不可抢占:其他线程不能强行抢占线程T1占有的资源循环等待:线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源。

m0_59372522的博客 634

【LangChain4J-09】开发学习知识点

本质是【三】工具循环的升级:模型拿到任务,自己决定调哪些工具、调几次,直到能回答。A:稳定内容(system/RAG/样例/工具 schema)放最前,易变内容(时间/本轮问题)放最后;prompt 归一化。A:需要精细控制防跑飞(maxSteps)、SSE 逐字事件粒度、可观测埋点(tool_count/first_token_ms),声明式在这些点上的可控性不足。:稳定不变的内容(人设、规则、RAG 文档、样例)放最前,易变内容(时间戳、本轮问题)放最后——这直接决定【缓存章节】的命中率。

weixin_44823875的博客 322

一文详解响应式编程springwebflux

详解springwebflux使用

工匠精神coding,终生学习 1244

面试与压测问题汇总

回答框架(STAR 法则):背景 (S): XX公司业务线众多(金融租赁、保险、营销、物流、发票等),每个迭代需要大量回归测试,手工执行效率低、覆盖不全。任务 (T): 负责设计和开发公司级的 API 自动化测试平台,覆盖多条业务线的接口回归、流程编排和版本对比。基于 Spring Boot + TestNG + llrunner 搭建分层架构设计 Component → Flow → Factory → TestCase 四层架构。

weixin_46921460的博客 554
上一篇: 【Exception】fastjson的toJSONString()导致OOM
下一篇: 【MySQL】升级增量脚本的编写
ColdFireMan
博客等级 码龄10年 27粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值