ThreadLocal可以称为线程本地变量或线程本地存储,跟方法内作用域的变量一样,都是本线程私有的。可以用来在一个线程调用多个方法的过程中、用来传递参数,省去通过方法入参传递的麻烦。slfj的MDC,多数据源,以及弱引用WeakReference等等场景中都可以看到ThreadLocal的应用。
线程本地存储:在线程生命周期内作为上下文存储共享对象
这里的上下文指的是线程存活期间内,调用多个方法,各个方法之间共享的“上下文空间”。
我们知道,每个线程对应着它的线程栈,线程栈由栈帧组成,用这套数据结构来跟踪线程的方法调用。
每个栈帧里边存放着一个方法内的局部变量,进入一个方法则压入一个栈帧,从一个方法返回则弹出一个栈帧。
考虑一个问题:如果想在一个thread生命周期内,在多个栈帧或者说多个方法之间共享对象呢?
用局部变量显然不行,其作用域只在方法里或者栈帧内,每个栈帧维护自己的局部变量表,另一个栈帧不认识。thread里边弄个静态变量当然可以,但是这是类级别的、就对别的thread实例可见,要考虑并发问题了。
想来想去,在Thread类的内部的成员变量中搞个Map来存放这些值是个不错的主意:作用域是每个thread实例,酷我音乐能够被线程生命周期内各个方法调用所共享。我想这就是ThradLocalMap和ThreadLocal的由来。
ThreadLocal的使用方法
先看例子程序:
使用ThreadLocal在线程的多个方法调用之间共享参数
public class WorkerThread implements Runnable{
public static ThreadLocal<Map> paramA = new ThreadLocal<>();
private CountDownLatch latch;
public WorkerThread(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
ThreadLocalTest tlt = new ThreadLocalTest();
tlt.initParamA();
tlt.useParamA();
latch.countDown();
}
}
public class ThreadLocalTest {
private static Logger logger = L