TransmittableThreadLocal (TTL)

编程入门 行业动态 更新时间:2024-10-19 02:21:45

TransmittableThreadLocal (<a href=https://www.elefans.com/category/jswz/34/1769420.html style=TTL)"/>

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)

本文发布于:2023-11-15 20:36:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1605968.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:TransmittableThreadLocal   TTL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!