ThreadLocal 应用
利用threadLocal 把拦截器中的对象传递到controller或service中
1.可以用 request 携带数据。
2.更优雅的方式是用threadlocal。
请求进入tomcat 和产生响应前,都处于同一个线程中比如在一个登录拦截器中,在preHandle方法中登录成功后,放行前,想把user对象传到controller或service中,最后在拦截器的afterCompletion方法中移除。
创建一个类UserThreadLocal.java
public class UserThreadLocal {
//把构造函数私有,外面不能new,只能通过下面两个方法操作
private UserThreadLocal(){
}
private static final ThreadLocal<User> LOCAL = new ThreadLocal<User>();
public static void set(User user){
LOCAL.set(user);;
}
public static User get(){
return LOCAL.get();
}
}
相当于一个容器,此容器伴随着线程,线程启动,就有这个容器,销毁,容器就跟着销毁。生命周期就是这个线程。
在拦截器中,登录成功后,放行前加上
//登录成功
UserThreadLocal.set(user);//将user对象放置在本地线程中,方便controller和service获取
由于tomcat 的运行机制,要及时清空threadLocal的内容,以下可以放在拦截器的afterCompletion方法中
/*tomcat底层 每一个请求都是一个线程,如果每一个请求都启动一个线程,性能就会降低,
1. 于是就有了线程池,而线程池中的线程并不是真正销毁或真正启动的。
2. 也就是说这个请求的线程是个可复用的线程,第二次请求可能还会拿到刚刚的线程,
3. 若不清空,里面本身就有user对象,数据会错乱*/
UserThreadLocal.set(null); //清空本地线程中的user对象数据
在controller 或 service 中调用
User user = UserThreadLocal.get();
实现ThreadLocal复制到新线程@Async
方法一:
如何在子线程和线程池中使用 ThreadLocal 传输上下文
方法二:
第一步:自定义Spring线程池
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setTaskDecorator(new UserThreadLocalTaskDecorator());
executor.initialize();
return executor;
}
第二步:自定义TaskDecorator
/**
* @author kancy
* @version 1.0
* @date 2019/4/24 11:01
*/
public class UserThreadLocalTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
// 从当前线程中获取user
User user = UserThreadLocal.get();
Runnable newRunnable = new Runnable(){
@Override
public void run() {
try{
// 放到新线程中
UserThreadLocal.set(user);
runnable.run();
}finally {
UserThreadLocal.set(null);
}
}
};
return newRunnable;
}
}
参考:
https://github.com/moelholm/smallexamples/tree/master/spring43-async-taskdecorator
https://moelholm.com/2017/07/24/spring-4-3-using-a-taskdecorator-to-copy-mdc-data-to-async-threads/
http://www.sohu.com/a/280604362_100270933
ThreadLocal 应用的更多相关文章
- ThreadLocal简单理解
在java开源项目的代码中看到一个类里ThreadLocal的属性: private static ThreadLocal<Boolean> clientMode = new Thread ...
- Android线程管理之ThreadLocal理解及应用场景
前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...
- Threadlocal使用Case
Threadlocal能够为每个线程分配一份单独的副本,使的线程与线程之间能够独立的访问各自副本.Threadlocal 内部维护一个Map,key为线程的名字,value为对应操作的副本. /** ...
- 多线程映射工具——ThreadLocal
ThreadLocal相当于一个Map<Thread, T>,各线程使用自己的线程对象Thread.currentThread()作为键存取数据,但ThreadLocal实际上是一个包装了 ...
- ThreadLocal 工作原理、部分源码分析
1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...
- ThreadLocal<T>的是否有设计问题
一.吐槽 ThreadLocal<T>明显是.NET从JAVA中来的一个概念,但是这种设计是否出现了问题. 很明显,在JAVA中threadLocal直接是Thread的成员,当然随着th ...
- 理解ThreadLocal —— 一个map的key
作用: 当工作于多线程中的对象使用ThreadLocal维护变量时,threadLocal为每个使用该变量的线程分配一个独立的变量副本. 接口方法: protected T initialValue( ...
- JavaSe:ThreadLocal
JDK中有一个ThreadLocal类,使用很方便,但是却很容易出现问题.究其原因, 就是对ThreadLocal理解不到位.最近项目中,出现了内存泄漏的问题.其中就有同事在使用ThreadLocal ...
- 0041 Java学习笔记-多线程-线程池、ForkJoinPool、ThreadLocal
什么是线程池 创建线程,因为涉及到跟操作系统交互,比较耗费资源.如果要创建大量的线程,而每个线程的生存期又很短,这时候就应该使用线程池了,就像数据库的连接池一样,预先开启一定数量的线程,有任务了就将任 ...
- ThreadLocal 源码剖析
ThreadLocal是Java语言提供的用于支持线程局部变量的类.所谓的线程局部变量,就是仅仅只能被本线程访问,不能在线程之间进行共享访问的变量(每个线程一个拷贝).在各个Java web的各种框架 ...
随机推荐
- 前端学习记录 week 1
前端学习记录 week 1 基础知识 CSS盒模型 所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用.CSS盒模型本质上是一个盒子,封 ...
- 小白的git克隆流程clone
首先你进去你要存放代码的位置,比如将代码存放到D盘,然后在D盘中右键,点击Git Bash Here,就是说本地仓库要在D盘建立. 然后出现git 命令行界面,然后输入命令:git clone + 远 ...
- ora600
4节点RAC:版本oracle11.2.0.4 22:20——23:40发生ora600 alert日志: Errors in file /u01/app/oracle/diag/rdbms/orcl ...
- Ffmpeg AAC 编码错误 Input contains (near) NaN/+-Inf
Ffmpeg AAC编码 如果传入参Frame的Sample Format 为 AV_SAMPLE_FMT_S16,会出现 错误提示 Input contains (near) NaN/+-Inf,需 ...
- 16/7/7_PHP-构造\解析函数
昨天又问老师问题,老师还是强调要用博客之类记录下每天的学习的习惯. 我个人的想法是一些知识点不用笔记一下 在脑海的理解不是太深.但是老师都这么说了我老师乖乖的记录下今天的学习的一些知识.心得.技巧等等 ...
- linux系统镜像iso文件下载
linux系统镜像iso文件下载 首先你要选择你想要的linux版本,常见版本有CentOS,Ubuntu.选择一个你需要的. 有两个镜像站推荐: 网易镜像站:http://mirrors.163.c ...
- SpringBoot(三) -- SpringBoot与日志
一.日志的起源 现在假设一个开发人员在开发一个大型系统,由于这个系统过于庞大没在很多的地方将关键的数据使用System.out.println()打印,但是当我们在项目正式上线时又需要去除,在项目bu ...
- OOM排除与JVM调优
仅先记录,后续整理 1. 常用命令: jstat gcutil jmap 2. 打印GC执行情况: 通过执行jinfo -flag +PrintGCDetails <pid>直接动态开启, ...
- Java RPC 分布式框架性能大比拼,Dubbo排老几?
来源:http://985.so/aXe2 Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成 ...
- JDK11 | 第二篇 : JShell 工具
文章首发于公众号<程序员果果> 地址 : https://mp.weixin.qq.com/s/saHBSTo4OjsIIqv_ixigjg 一.简介 Java Shell工具是JDK1. ...