TransmittableThreadLocal (TTL)

2023-11-07 11:12

本文主要是介绍TransmittableThreadLocal (TTL),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

官方文档

问题描述

在日常的开发中,我们经常会通过多线程来提高业务执行效率,例如:

当前登录用户信息放在ThreadLocal内,然后service在处理业务逻辑时通过线程池来异步的处理,由于线程池内的线程与当前主线程不是同一个,因此获取不到主线程存放的用户信息

Runnable runnable = ()->{while(true){//处理用户数据-会从ThreadLoca内获取登录人信息System.out.println("当前ThreadLocal值为=>"+threadLocal.get());try {ThreadUtil.sleep(1000);} catch (Exception e) {throw new RuntimeException(e);}}
};Runnable runnable2 = ()->{//处理订单数据-会从ThreadLoca内获取登录人信息System.out.println("当前ThreadLocal值为=>"+threadLocal.get());
};
//异步处理用户数据
CompletableFuture.runAsync(runnable,executor);
//主线程操作
threadLocal.set("hello TTL");//异步处理订单数据
CompletableFuture.runAsync(runnable2,executor);

JDK为我们提供了 InheritableThreadLocal,但是他只有在创建新线程时才会拷贝(一个新线程只拷贝一次),而线程池内的核心线程是不会销毁的,会处理多个任务,因此就无法获取到当前登录人信息(或者会获取其他人的登录信息)。

这种情况我们就可以使用Alibaba为我们提供的 TransmittableThreadLocal来解决这个问题。

TTL使用

TransmittableThreadLocal继承自InheritableThreadLocal,并扩展了多次拷贝主线程ThreadLocal的功能。

示例:

/**
*打印结果:修改为hello TTLpool-1-thread-1当前ThreadLocal值为=>0pool-1-thread-1当前ThreadLocal值为=>0pool-1-thread-1当前ThreadLocal值为=>0pool-1-thread-1当前ThreadLocal值为=>hello TTLpool-1-thread-1当前ThreadLocal值为=>hello TTLpool-1-thread-1当前ThreadLocal值为=>hello TTL
*/
public class TestTTL {//创建线程池static ExecutorService executor = new ThreadPoolExecutor(1,1,5,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10),new ThreadPoolExecutor.CallerRunsPolicy());//使用TransmittableThreadLocalstatic TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();public static void main(String[] args){threadLocal.set("0");Runnable runnable = ()->{for(int i=0;i<3;i++){//处理用户数据System.out.println(Thread.currentThread().getName()+"当前ThreadLocal值为=>"+threadLocal.get());ThreadUtil.sleep(1000);}};//执行任务1 注意此处需要通过 TtlRunnable.get(runnable)改变runnable类CompletableFuture.runAsync(TtlRunnable.get(runnable), executor);//主线程 修改 ThreadLocalthreadLocal.set("hello TTL");System.out.println("修改为hello TTL");//执行任务2CompletableFuture.runAsync(TtlRunnable.get(runnable),executor);executor.shutdown();}
}

Agent方式无侵入实现

上面的代码中我们使用了 TransmittableThreadLocal,然后在提交Runnable任务时我们需要通过 TtlRunnable.get(runnable) 来修饰Runnable。但是如果我们项目中的代码已经写好了,如果要修改成本很大,此时就可以通过Agent挂载的方式来动态修改Runnable类

方法:启动时配置 javaagent

java -javaagent:C:\Users\gudian\Desktop\test\transmittable-thread-local-2.14.2.jar 
-jar my.jar

这篇关于TransmittableThreadLocal (TTL)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/363234

相关文章

SOMEIP_ETS_095: SD_Check_subscribe_eventgroup_ttl_expired

测试目的: 验证DUT(Device Under Test)能够检测到测试器(Tester)的订阅已过期(ttl = 3秒),并且在TTL过期后不响应测试器触发的事件。 描述 本测试用例旨在确保DUT能够识别测试器的订阅已过期,并在订阅过期后不响应测试器通过TriggerEventUint8方法触发的事件。 测试拓扑: 具体步骤: TESTER:发送订阅事件组消息,用于事件组0x0

士兰微 SC32F5432 通过配置寄存器方式 将管脚配成开漏输出模式和TTL输入模式

目录 前言: 士兰微电子介绍 士兰微 SC32F5432介绍 士兰微 SC32F5432 通过配置寄存器方式 将管脚配成开漏输出模式和TTL输入模式 开漏输出模式 TTL输入模式 前言: 下面是对我在工作时公司所使用的一款国产芯片(士兰微 SC32F5432)开发过程所遇到的一些问题的记录与解决。 士兰微电子介绍 杭州士兰微电子股份有限公司(600460)坐落于杭州

开漏输出和推挽输出区别TTL电平和CMOS电平的区别

目录 开漏输出和推挽输出区别 参考附件: 正文: TTL电平和CMOS电平的区别 参考附件: 1.TTL电平: 2.CMOS电平: 3.电平转换电路:  开漏输出和推挽输出区别 参考附件: 开漏输出、推挽输出的区别_开漏输出和推挽输出区别-CSDN博客 正文: 推挽输出和开漏输出的主要区别体现在电路结构、工作原理以及应用场景上。 推挽输出由两个晶体管构成,一个N

串口助手使用和插入usb转TTL的COM口识别问题

问题出现原因 由于串口调试中经常需要通过断电对单片机烧录程序,所以制作了一个转接带开关的USB 转接口,如下图所示,其中按键控制的是OUT口的电源通断。但为了能够数据传输,有两根传输数据的线是一直连接的。在使用usb进行程序烧录中没有问题,后来使用USB转ttl连接串口助手时发现串口助手无法识别串口了。 解决方式及分析 把USB转TLL的RX和TX连接单片机,电源也同时连接好,然后4条线

线程间数据传递之ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal

线程间数据传递之ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal 1、ThreadLocal介绍 spring 中基于 ThreadLocal 来实现事务。 多线程 访问同一个共享变量的时候容易出现并发问题,ThreadLocal是除了加锁这种同步方式之外的一种保证 规避多线程访问出现线程不安全的方法,当我们在创建一个变

消息过期时间设置:队列属性与消息TTL

消息过期时间设置:队列属性与消息TTL 1. 设置队列属性2. 对消息本身进行TTL设置3. 同时使用时的TTL确定 💖The Begin💖点点关注,收藏不迷路💖 在消息队列(MQ)中,设置消息的过期时间是常见需求。这可通过两种方式实现:设置队列属性,使所有消息具有相同过期时间;或对消息本身进行单独TTL设置,每条消息TTL可不同。本文探讨这两种方法,并说明同

TransmittableThreadLocal

为了防止提交表单的时候携带的个人信息被篡改,我们经常使用token保存用户的个人信息,每次调用都是传token解析出个人信息,保存在当前的线程中,在哪里使用了我们就在线程中取出,防止提交人和个人信息不一致。 在使用线程池上下文存取用户信息在 当前线程中接口登录的时候获取token 解析token信息 将用户信息添加TransmittableThreadLocal的实例中,防止提交的用户信息被

双通道SP3232芯片实现由TTL电平转RS232电平

首先,单片机的串口必须经过电平转换才可以和标准RS-232通信,这个转换芯片5V的一般是MAX232或SP232,3.3V的一般是MAX3232或SP3232。 严格说,SP有3232和SP232两种,前者宽电,后者只支持5V。 SP3232是一款RS-232接口收发器芯片,其主要功能是串行转并行和并行转串行数据的转换。SP3232的引脚如下: 插一段,SP3232和SP3222的区别: 在

【Redis】获取没有设置ttl的key脚本

一 前言 在运维Redis的时候,总会遇到使用不规范的业务设计,比如没有对key设置ttl,进而导致内存空间吃紧,通常的解决方法是在slave上dump 出来所有的key ,然后对文件进行遍历再分析。遇到几十G的Redis实例,dump + 分析 会是一个比较耗时的操作,为此,我开发了一个小脚本直接连接Redis 进行scan 遍历所有的key,然后在检查key的ttl,将没有ttl的key输出到