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

TransmittableThreadLocal简单使用

一.简介:

TransmittableThreadLocal 是阿里包的一个 Java 类,它继承了InheritableThreadLocal,它解决了InheritableThreadLocal在主子线程和线程池传递threadlocal值的不足之处.

它是怎么解决主线程传递给子线程threadLocal的值的,  

答: 主线程传递子线程时,      它把threadLocal对象放到了 线程任务runnable里,  然后主线程把线程任务runnable传给了子线程, 然后子线程再从线程任务runnable里获得threadLocal的值,  就是这么简单.

二.所用依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>transmittable-thread-local</artifactId><version>2.14.2</version>
</dependency>

三.基本使用步骤:

1. 创建 TransmittableThreadLocal 对象,并指定泛型类型为要传递的变量类型:

TransmittableThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal<>();

2.在需要传递变量值的线程中,通过 set 方法设置变量的值:

transmittableThreadLocal.set("Hello, World!");

 3.在其他线程中,通过 get 方法获取传递的变量值:

String value = transmittableThreadLocal.get();

4.在使用完变量后,应该及时调用 remove 方法来清理对应的变量值,以避免内存泄漏:

transmittableThreadLocal.remove();

四.几个简单的示例

1. 直接使用 TransmittableThreadLocal

public class TransmittableThreadLocalDemo {private static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();public static void main(String[] args) {// 在主线程中设置TransmittableThreadLocal的值threadLocal.set("Hello, World!");// 在新线程中获取TransmittableThreadLocal的值Thread thread = new Thread(() -> {String value = threadLocal.get();System.out.println("TransmittableThreadLocal value in new thread: " + value);});thread.start();}
}

在这个示例中,我们首先在主线程中将一个字符串存储到TransmittableThreadLocal中。然后,我们创建一个新线程,在新线程中获取TransmittableThreadLocal的值并打印出来。由于TransmittableThreadLocal可以正确地传递数据,因此新线程中获取到的值与主线程中设置的值是相同的。

2. 在使用线程池的情况下使用 TransmittableThreadLocal

 在使用线程池的情况下,如果需要使用TransmittableThreadLocal,可以使用阿里巴巴的TTL库来实现。TTL库提供了一些工具类,可以方便地在使用线程池的情况下使用TransmittableThreadLocal。

        具体来说, 可以使用TtlRunnable和TtlCallable等类来包装 Runnable 和 Callable,从而在执行任务时自动传递ThreadLocal的值。例如,下面是一个使用线程池和TransmittableThreadLocal的示例:

public class ThreadPoolDemo {private static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(2);// 在主线程中设置TransmittableThreadLocal的值threadLocal.set("Hello, World!");// 在线程池中执行任务executorService.execute(TtlRunnable.get(() -> {String value = threadLocal.get();System.out.println("TransmittableThreadLocal value in new thread: " + value);}));// 等待任务执行完成executorService.shutdown();executorService.awaitTermination(1, TimeUnit.SECONDS);}
}

3. 使用 TtlExecutors 的使用案例 (推荐)

        TtlExecutors是阿里巴巴开源的一个工具类,用于在使用线程池的情况下使用TransmittableThreadLocal。具体来说,TtlExecutors提供了一些工具方法,可以方便地将线程池和TransmittableThreadLocal结合起来使用。

下面是一个使用TtlExecutors的示例代码:      

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.threadpool.TtlExecutors;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TtlExecutorsDemo {private static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();public static void main(String[] args) {// 创建一个固定大小的线程池ExecutorService executorService = Executors.newFixedThreadPool(2);// 在主线程中设置TransmittableThreadLocal的值threadLocal.set("Hello, World!");// 使用TtlExecutors包装线程池ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(executorService);// 提交任务到线程池中ttlExecutorService.submit(() -> {String value = threadLocal.get();System.out.println("Task is running in thread: " + Thread.currentThread().getName() + ", TransmittableThreadLocal value: " + value);});// 关闭线程池ttlExecutorService.shutdown();}
}

五. 拓展


        除了在使用线程池的情况下使用TransmittableThreadLocal外,还有一些其他的使用案例。

例如,在使用Dubbo等分布式框架时,TransmittableThreadLocal可以用于在服务调用链路中传递数据。具体来说,可以在服务提供者和消费者中使用TransmittableThreadLocal来传递一些上下文信息,例如请求ID、用户信息等。这样可以方便地在服务调用链路中获取这些信息,从而实现一些功能,例如日志追踪、权限校验等。

另外,TransmittableThreadLocal还可以用于一些需要在多个线程之间共享数据的场景。例如,在使用Netty等网络编程框架时,可以使用TransmittableThreadLocal来在不同的事件处理器之间共享一些上下文信息,例如连接信息、请求信息等。

总之,TransmittableThreadLocal可以用于在多线程环境下传递数据,解决了ThreadLocal在多线程环境下的一些问题。在使用TransmittableThreadLocal时需要注意一些细节,例如需要进行垃圾回收等。同时,也需要根据具体的使用场景来选择合适的使用方式。


http://www.mrgr.cn/news/28955.html

相关文章:

  • 网站架构知识之nginx第三天(day026 )
  • 数据仓库面试题集离线实时
  • 如何平滑切换Containerd数据目录
  • 云原生学习
  • 正则表达式那些事儿
  • vue3面试题1|[2024-11-12]
  • UVA-211 多米诺效应 题解答案代码 算法竞赛入门经典第二版
  • 嵌入式DCMI摄像头功能调试方法
  • ChatGLM-6B部署到本地电脑
  • Chainlit集成Langchain并使用通义千问AI知识库高级检索(多重查询)网页对话应用教程
  • C++:析构函数
  • 全面掌握 Jest:从零开始的测试指南(下篇)
  • Python JSON
  • 分析和管理远程服务器方法
  • Netty笔记09-网络协议设计与解析
  • vue3 表单校验规则封装
  • 【docker学习笔记】docker概念和命令
  • 我的5周年创作纪念日,不忘初心,方得始终。
  • CI/CD持续集成和持续交付(git工具、gitlab代码仓库、jenkins)
  • Vue3项目开发——新闻发布管理系统(七)
  • Koa安装和应用
  • RocksDB系列一:基本概念
  • 超全网络安全面试题汇总(2024版)
  • list从0到1的突破
  • 精选评测!分享5款AI写论文最好用的软件排名
  • Get包中的根组件