在使用线程池等会缓存线程的组件情况下传递ThreadLocal
最近开发的系统有一个场景在多个RPC调用链中需要传递一些公有参数过去。
这个时候首先想到的是ThreadLocal,但是有一个问题就是它不能在父子线程中传递上下文信息(ThreadLocal变量信息),这时我们考虑用InheritableThreadLocal,它可以解决父子线程中上下文的传递,但是又发现一个问题,InheritableThreadLocal在线程池复用的组件里无法复制,最后我们这个时候考虑用TransmittableThreadLocal 解决 ,TransmittableThreadLocal这个类是来自阿里的一个开源项目:https://github.com/alibaba/tr...。这个类就是为了解决例如使用线程池、Tomcat这类缓存线程组件,如ThreadPoolExecutor、tomcat线程池的时候,某一线程中的数据和ThreadLocal等在没有删除或者解绑的情况下,会被下一个Runable类或者Http请求复用。而在提交任务给线程池时,而TransmittableThreadLocal为了解决这个问在提交任务给线程池时,将ThreadLocal数据一起提交,相当于重新set一次ThreadLocal。
当然光这个还不够,我们还要把线程池增强或者使用TtlRunnable.get()的方式,看下面代码例子
package com.jd.neptune.site.util.util;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;
import com.alibaba.ttl.threadpool.TtlExecutors;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TestTransmittableThreadLocal {private static TransmittableThreadLocal<String> ttl = new TransmittableThreadLocal<>();private static ThreadLocal tl = new ThreadLocal();private static ExecutorService executorService = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(1));private static ExecutorService executorService2 = Executors.newFixedThreadPool(1);public static void main(String[] args) {for (int i = 0; i < 3; i++) {ttl.set("#" + i);tl.set("#" + i);
// System.out.println("main-"+ttl.get());
// executorService.execute(() -> {
// System.out.println("child-pool-ttl-" + ttl.get());
// System.out.println("child-pool-tt-" + tl.get());
// });
// executorService2.execute(TtlRunnable.get(() -> {
// System.out.println("child-pool2-ttl-" + ttl.get());
// System.out.println("child-pool2-tt-" + tl.get());
// }));
// new Thread(() -> {
// System.out.println("child-new-ttl-" + ttl.get());
// }
// ).start();
// new Thread(() -> {
// System.out.println("child-new-tl-" + tl.get());
// }
// ).start();executorService2.execute(() -> {System.out.println("child-pool2-ttl-" + ttl.get());System.out.println("child-pool2-tt-" + tl.get());});new Thread(() -> {System.out.println("child-new-ttl-" + ttl.get());}).start();}}
}
在使用线程池等会缓存线程的组件情况下传递ThreadLocal相关推荐
- 【Android 异步操作】线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTask 使用线程池示例 )
文章目录 一.线程池简介 二.线程池初始化方法简介 三.线程池使用示例 一.线程池简介 线程池一般是实现了 ExecutorService 接口的类 , 一般使用 ThreadPoolExecutor ...
- 什么是线程池和常用的线程池
创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限.为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池, ...
- JAVA线程池_并发队列工作笔记0003---线程池的分类_可缓存线程池_定长线程池_定时线程池_单例线程池
技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 这里说线程池的分类 有可缓存类型, 定长类型, 定时类型, 单例类型, 这里我这次用Executo ...
- boost创建线程池_Java并发 之 线程池系列 (1) 让多线程不再坑爹的线程池
目录 背景 线程池的来由 什么是线程池 背景总结 用法 通过Executors创建线程池 Executors及其服务的类 Executors常用的几个方法 一个线程池的例子 任务 池子 测试 说明 总 ...
- 线程池默认多少个线程_我需要多少个线程?
线程池默认多少个线程 这取决于您的应用程序. 但是,对于那些希望对如何从生产站点购买的所有昂贵内核中挤出大量资金的人,请多多包涵,我将阐明围绕多线程 Java应用程序的奥秘. 内容针对最典型的Java ...
- java 线程池数量_java线程池及创建多少线程合适
java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...
- java线程池的应用_Java线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- 线程池详解:线程池的七大参数及运行流程
尽管 Executors 的工厂方法使用方便,在生产场景被很多企业的开发规范所禁用.要求通过标准构造器 ThreadPoolExecutor 去构造工作线程池. 1. 核心数据结构 public cl ...
- Android性能优化之线程池策略和对线程池的了解
转载于 http://blog.csdn.net/roshen_android/article/details/52948480 线程的运行机制 1. 开启线程过多,会消耗cpu 2. 单核cpu,同 ...
最新文章
- ubuntu 12.04安装 jdk
- simple css 汉化,Simple CSS(CSS文档生成器)
- C#的多线程(2)——机制探索
- python爬取考研成绩什么时候出来_用Python爬取了考研吧1000条帖子,原来他们都在讨论这些!...
- mutex_lock
- 电脑安装了mysql,但找不到mysql服务
- 排序及查找----[(冒泡,快速)(拉格朗日,二分)]
- xshell安装步骤
- cmd 修改ie快捷方式_windows使用技巧之Win + R 与 CMD 的不同
- 电路基础知识 -- 虚短和虚断
- 弱电机房如何理线整理机柜?值得收藏学习
- linux卸载windows boot,windows和Linux双系统卸载Linux系统
- 一篇文章搞定Redis Stream
- matlab+butter+多维,matlab butter c实现
- Linux 系统进程管理
- UE_材质_UV计算相关
- 盘古开源在芯片领域崛起,专注于芯片研发
- Multiple users(Guest mode) 多用户或访客模式调试
- 准备春招 CSDN博客不定期脱更 见谅
- 怎么实现全国IP自动更换?