TPS04-J. 使用线程池时确保ThreadLocal变量每次都初始化
线程池可以提供这种保障,一旦你的代码开始执行了,被分配来执行这个task的线程在执行完你的task之前不会做别的事情。
所以不用担心执行到一半被别的task改了 thread local 的变量。
由于线程重复使用所以你对thread local变量的修改都会保留下来
所以在使用前要把变量“重置”一下。 可以在每个task结尾做,也可以在开始做。
在结尾做的话需要放到finally里,确保执行
public final class Diary {
// ...
public static void removeDay() {
days.remove();
}
}
public final class DiaryPool {
// ...
public void doSomething1() {
exec.execute(new Runnable() {
@Override
public void run() {
try {
Diary.setDay(Day.FRIDAY);
diary.threadSpecificTask();
} finally {
Diary.removeDay(); // 就是这里
}
}
});
}
// ...
}
另一个方法是在每次执行task之前做清理。
具体实现起来就是对executor进行扩展实现 beforeExecute 方法
class CustomThreadPoolExecutor extends ThreadPoolExecutor {
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
public void beforeExecute(Thread t, Runnable r) {
if (t == null || r == null) {
throw new NullPointerException();
}
Diary.setDay(Day.MONDAY);
super.beforeExecute(t, r);
}
}
TPS04-J. 使用线程池时确保ThreadLocal变量每次都初始化的更多相关文章
- 在使用线程池时应特别注意对ThreadLocal的使用
使用ThreadLocal并且有线程池时要特别注意,ThreadLocal是以线程为key的,而线程池里面的线程是会被重新利用的,所以如果有使用线程池并且使用ThreadLocal来保存状态信息时要特 ...
- ThreadLocal遇到线程池时, 各线程间的数据会互相干扰, 串来串去
最近遇到一个比较隐蔽而又简单地问题,在使用ThreadLocal时发现出现多个线程中值串来串去,排查一番,确定问题为线程池的问题,线程池中的线程是会重复利用的,而ThreadLocal是用线程来做Ke ...
- 使用Hystrix的插件机制,解决在使用线程隔离时,threadlocal的传递问题
背景 在我们的项目中,比较广泛地使用了ThreadLocal,比如,在filter层,根据token,取到用户信息后,就会放到一个ThreadLocal变量中:在后续的业务处理中,就会直接从当前线程, ...
- Git提交(PUSH)时记住密码 - 不用每次都输入密码
开发使用的团队搭建好的GitLab服务器来作为项目共享开发,由于我不是最高权限,没办法把我git生成的SSH-Key放到服务器里面去,所有只好在每次提交的时候配置git config来记录密码不过期来 ...
- 线程池及Executor框架
1.为什么要使用线程池? 诸如 Web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过 ...
- 深入理解Java多线程——线程池
目录 为什么需要线程池 定义 ThreadPoolExecutor 工作队列workQueue 不同的线程池 Executor 线程池的工作原理 线程池生命周期 线程池增长策略 线程池大小的设置 线程 ...
- 线程池-Threadlocal
ThreadLoclc初衷是线程并发时,解决变量共享问题,但是由于过度设计,比如弱引用的和哈希碰撞,导致理解难度大.使用成本高,反而成为故障高发点,容易出现内存泄露,脏数据.贡献对象更新等问题.单从T ...
- 阿里开源支持缓存线程池的ThreadLocal Transmittable ThreadLocal(TTL)
功能 在使用线程池等会缓存线程的组件情况下,提供ThreadLocal值的传递功能. JDK的InheritableThreadLocal类可以完成父子线程值的传递. 但对于使用线程池等会缓存线程的组 ...
- j.u.c系列(01) ---初探ThreadPoolExecutor线程池
写在前面 之前探索tomcat7启动的过程中,使用了线程池(ThreadPoolExecutor)的技术 public void createExecutor() { internalExecutor ...
随机推荐
- VNC安装与使用
查看是否安装VNC:rpm -qa | grep vnc 安装VNC:rpm -ivh vnc-4.1.2-14.el5_3.1.i386.rpm ,rpm -ivh vnc-server-4.1.2 ...
- redis数据类型之—Set
(1)set 简单介绍 set集合的数据是不重复的.无序的,一个集合类型键可以存储至多2^32-1 个字符串. (2)set 常用命令
- tftp服务器的搭建
基于 红帽6的tftp搭建,当然其他系统搭建方法也大致一样 #mount /dev/cdrom /mnt/ 挂载安装光盘 不同光盘挂载用 fdisk -l 查看光盘 #rpm ...
- 关于 《cocoapods 的taobao的镜像停止更新问题》
cocoapods 的ruby.taobao.org 停止更新了!!!!!! 最近一直在改老项目,突然听伙伴说:cocoapods 的ruby.taobao.org 停止更新了.很是吃惊,遂即闯入:h ...
- Page-encoding specified in XML prolog (UTF-8) is different from that specified in page directive (utf-8)
org.apache.jasper.JasperException:xxx.jsp(1,1) Page-encoding specified in XML prolog (UTF-8) is diff ...
- iOS 自定义的CodeSnippets添加按下tab键切换到指定输入位置
在需要使用tab来选中并输入内容的地方,添加: <#输入待覆盖的内容#>
- PHP实现快速排序、插入排序、选择排序
1.快速排序 快速排序(Quicksort)是对冒泡排序的一种改进.由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都 ...
- day1 初识Linux
linux 基础 1.Linux简介1) 掌握Linux的定义:Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统. ...
- JavaScript-table+大图滚动
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Canvas 实现七彩喷泉
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...