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

阿里TTL(Transmittable Thread Local)实现原理

TTL简介

TTL全称Transmittable Thread Local,是阿里开源的一个用于解决线程池场景下,ThreadLocal变量无法在子线程中继承的问题。

TTL核心原理简介

首先我们知道InheritableThreadLocal允许在创建子线程时,子线程继承(复制)父线程的值,但这个继承操作是在构造方法中实现的,也就是线程第一次创建的时候实现的。因为这个特点,在线程池场景下,InheritableThreadLocal子线程就没有办法继承父线程的值了。

那么TTL是怎么做到的?在介绍原理之前,我们先来简单的使用一下InheritableThreadLocal。

TTL使用案例

在下面的代码中
1、首先我们定义了一个TransmittableThreadLocal的context变量
2、我们创建了只有一个线程的线程池,并提交了一个任务,模拟线程池中的线程已经被创建
3、后面我们在主线程中,往context中设置一个值
4、后面提交了俩次任务。第一次提交,使用未包装的任务,子线程无法获取到主线程设置的值。第二次提交使用TtlRunnable对任务进行了包装,子线程成功获取到了值
5、在第二次任务中,子线程修改了context中的值,但最终主线程的值并不会受到影响

public class TTLDemo {// 1. 定义TTL变量private static final TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService executor = Executors.newFixedThreadPool(1);executor.submit(() -> System.out.println("初始化线程" + Thread.currentThread())).get();// 2. 主线程设置值context.set("Global-Context-Value");System.out.println("[Main] 设置值: " + context.get());// 3. 提交任务(未包装)- 无法传递值!executor.submit(() -> System.out.println("[Task-RAW] 读取值: " + context.get()) // 输出 null);// 4. 创建可传递任务Runnable task = () -> {System.out.println("[Task-TTL] 读取值: " + context.get());// 子线程修改值(不会影响父线程)context.set("Sub-Thread-Modified");System.out.println("[Task-TTL] 修改后: " + context.get());};// 5. ⭐ 关键:包装任务Runnable ttlTask = TtlRunnable.get(task);// 6. 提交包装后的任务executor.submit(ttlTask); // 7. 主线程值保持不变Thread.sleep(500);System.out.println("[Main] 最终值: " + context.get()); // 仍为 Global-Context-Valueexecutor.shutdown();}
}

在上面的案例中,我们提交任务前,需要使用TtlRunnable.get()对要提交的任务包装一层,这样ttl才能生效。但如果每次都需要我们自己包装,就有点麻烦。这时候我们可以使用自动包装线程池,由线程池自动来帮助我们实现任务的包装。修改后的代码如下,

使用TtlExecutors.getTtlExecutorService()对我们的线程池进行包装。

    // 1. 定义TTL变量private static final TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService executor = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(1));executor.submit(() -> System.out.println("初始化线程" + Thread.currentThread())).get();// 2. 主线程设置值context.set("Global-Context-Value");System.out.println("[Main] 设置值: " 
http://www.dtcms.com/a/603458.html

相关文章:

  • 做网站建设注册商标是多少类上海卫生人才网官网
  • 湖州网站制作报价多用户商城系统哪个公司的好
  • 网站建设教程 作业建电商网站
  • 泰兴市城乡住房建设局网站wordpress 商品导航菜单
  • 网站权重对优化的作用深圳小区封闭最新通知
  • 聊城市东昌府区建设局网站南京移动网站设计
  • 含重复元素的子集生成
  • 基于802.11的无线mesh网状网络
  • 公司官网网站建设wordpress 上传权限设置
  • 宿州高端网站建设公司哪家好wordpress启动命令
  • 水果套餐网站牡丹江seo
  • 微网站制作速成法网站建设哪家有实力
  • 建设官网站外国手机网站设计
  • 做交流网站网站qq访客记录原理
  • 网站设计赚钱吗帮别人做网站的合作协议
  • 柬埔寨做网站山东烟台城乡建设学校官方网站
  • 如何在供应商报价超出预算后重新谈判
  • 邙山郑州网站建设黑马培训
  • 网站代运营价格网店运营推广高级实训教程
  • 上海网站建设联系电话wordpress 数据库删除
  • 5.4、Python-数据的拼接
  • 简述网站开发建设的基本流程品牌设计的意义
  • 网站搜索栏怎么做织梦网站后台模版更换
  • 免费建设手机网站电子商务网站购物车怎么做
  • RC阻尼与RCD吸收电路
  • 网站免费空间网易企业邮箱和网易邮箱的区别
  • Linux下的花式「隔空」文件传输魔法
  • 建设广州公司网站甘肃建设体网站
  • 公司建设网站带来什么小程序官网平台入口
  • 相机与动画 - 3: