线程池可以提供这种保障,一旦你的代码开始执行了,被分配来执行这个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变量每次都初始化的更多相关文章

  1. 在使用线程池时应特别注意对ThreadLocal的使用

    使用ThreadLocal并且有线程池时要特别注意,ThreadLocal是以线程为key的,而线程池里面的线程是会被重新利用的,所以如果有使用线程池并且使用ThreadLocal来保存状态信息时要特 ...

  2. ThreadLocal遇到线程池时, 各线程间的数据会互相干扰, 串来串去

    最近遇到一个比较隐蔽而又简单地问题,在使用ThreadLocal时发现出现多个线程中值串来串去,排查一番,确定问题为线程池的问题,线程池中的线程是会重复利用的,而ThreadLocal是用线程来做Ke ...

  3. 使用Hystrix的插件机制,解决在使用线程隔离时,threadlocal的传递问题

    背景 在我们的项目中,比较广泛地使用了ThreadLocal,比如,在filter层,根据token,取到用户信息后,就会放到一个ThreadLocal变量中:在后续的业务处理中,就会直接从当前线程, ...

  4. Git提交(PUSH)时记住密码 - 不用每次都输入密码

    开发使用的团队搭建好的GitLab服务器来作为项目共享开发,由于我不是最高权限,没办法把我git生成的SSH-Key放到服务器里面去,所有只好在每次提交的时候配置git config来记录密码不过期来 ...

  5. 线程池及Executor框架

    1.为什么要使用线程池? ​ 诸如 Web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过 ...

  6. 深入理解Java多线程——线程池

    目录 为什么需要线程池 定义 ThreadPoolExecutor 工作队列workQueue 不同的线程池 Executor 线程池的工作原理 线程池生命周期 线程池增长策略 线程池大小的设置 线程 ...

  7. 线程池-Threadlocal

    ThreadLoclc初衷是线程并发时,解决变量共享问题,但是由于过度设计,比如弱引用的和哈希碰撞,导致理解难度大.使用成本高,反而成为故障高发点,容易出现内存泄露,脏数据.贡献对象更新等问题.单从T ...

  8. 阿里开源支持缓存线程池的ThreadLocal Transmittable ThreadLocal(TTL)

    功能 在使用线程池等会缓存线程的组件情况下,提供ThreadLocal值的传递功能. JDK的InheritableThreadLocal类可以完成父子线程值的传递. 但对于使用线程池等会缓存线程的组 ...

  9. j.u.c系列(01) ---初探ThreadPoolExecutor线程池

    写在前面 之前探索tomcat7启动的过程中,使用了线程池(ThreadPoolExecutor)的技术 public void createExecutor() { internalExecutor ...

随机推荐

  1. 第二十八篇:SOUI中自定义控件开发过程

    在SOUI中已经提供了大部分常用的控件,但是内置控件不可能满足用户的所有要求,因此一个真实的应用少不得还要做一些自定义控件. 学习一个新东西,最简单的办法就是依葫芦画瓢.事实上在SOUI系统中内置控件 ...

  2. [原创]Mac系统下制作OS 10.11安装镜像

    一.所需软件 1.从App Store下载OS X El Capitan 10.11.2 ------------------------------------------------------- ...

  3. sql Lloader

    create table ban_ji(id integer,ban_ji varchar2(25))insert into ban_ji values(1,'1-(1)');insert into ...

  4. java分享第八天-01(线程)

     创建线程:1 可以实现Runnable接口.2 可以扩展Thread类本身. 通过实现Runnable创建线程:创建一个线程,最简单的方法是创建一个实现Runnable接口的类.为了实现Runnab ...

  5. mysql错误汇总

    1,mysql报Fatal error encountered during command execution的解决办法 连接字符串里加上 Allow User Variables=True 解决. ...

  6. mysql基本语法

    MySql一些基本语法      3.3.5 直接在数据库目录中创建或删除 用上述方法创建数据库,只是MySQL数据目录下面创建一个与数据库同名目录,同样删除数据库是把这个目录删除. 所以,你可以直接 ...

  7. cuplayer酷播播放器 swf 带参数直接播放

    客户需要使用cuplayer,直接调用swf 播放器. /Player/player.swf?FlvID=745,此处写入视频ID; 官方给的例子,运行是有问题的. http://www.cuplay ...

  8. jquery数组(排序)

    sort(); html: <h3>字符串数组排序前</h3> <div id="show1"></div> <h3>排 ...

  9. 读书笔记:const和readonly、static readonly 那些事

    C#中表示不变的量(常量)的两种形式:const 和readonly const 是静态常量 readonly 是动态常量 严格的来讲:const 应该称为常量 而readonly 则应称为只读变量. ...

  10. 提倡IT从业人员终身学习

    经常听身边的团队成员抱怨,今天太累了,回到家连动都不想动;这形成了目前圈子里大多从业者的生活常态. 但有一部分人,在团队里身居要职,薪水不少拿却工作不那么累,你想过他们么? 答案很简单,人家会学习,而 ...