ThreadLocal是线程私有的本地变量,存储在Thread类的属性threadlocals中,该变量类型是ThreadLocal.ThreadLocalMap 类型是ThreadLocal的静态内部类,所有线程的本地变量都是由ThreadLocal类来维护,即通过内部类来存储该线程的本地变量集合
Thread属性
ThreadLocalMap是一个静态内部类
public class ThreadLocalTest extends ThreadLocal {
public static void main(String[] args) throws InterruptedException {
/**
* ThreadLocal 是一个本地变量,是本线程所私有的,其他线程不能访问,其绑定在Thread的threadLocals变量中,该变量是一个
* ThreadLocalMap类型,key是ThreadLocal变量,value是我们设置的值
* class Thread{
* 每个线程有个ThreadLocalMap集合 存储ThreadLocal变量
* ThreadLocal.ThreadLocalMap threadLocals = null;
* }
*/
ThreadLocal<Object> threadLocalA = new ThreadLocal<>();
ThreadLocal<Object> threadLocalB = new ThreadLocal<>();
Thread thread = new Thread(() -> {
//线程A设置threadLocalA的值
threadLocalA.set("threadLocalAValue1");
//线程A设置threadLocalB的值
threadLocalB.set("threadLocalAValue2");
System.out.println("线程A-->threadLocalA:" + threadLocalA.get());
threadLocalA.remove();
System.out.println("线程A-->threadLocalB:" + threadLocalB.get());
});
thread.start();
thread.join();
new Thread(()->{
//线程B设置threadLocalA的值
threadLocalA.set("threadLocalBValue1");
//线程B设置threadLocalB的值
threadLocalA.set("threadLocalBValue2");
System.out.println("线程B:-->threadLocalA" + threadLocalA.get());
threadLocalA.remove();
System.out.println("线程B:-->threadLocalA" + threadLocalA.get());
}).start();
}
}
A线程中设置了threadLocalA,threadLocalB两个变量,再调用threadLocalA移除该变量,在线程B中调用同一个threadLocalA.get()输出了另一个值threadLicalBValue,说明两个线程的变量是相互隔离的,同时ThreadLocalMap可以存储多个值
查看具体的方法执行
set方法,首先获取到当前线程,通过当前线程获取它的属性threadLocals
这也是为什么同一个变量在不同线程互不影响的原因,通过当前线程获取自己的threadLocals ,获取到后判断是否为空,若不为空则存储到本线程的threadLocals变量里,若为空则创建一个ThreadLocalMap
这里this指的是,因为是通过这个变量调用的,firstValue是里面的值,完成创建,赋值给当前线程
查看get()方法
同样是获取当前线程的threadLocalMap 不为空则去获取,这里this也是调用方法的那个ThreadLocal变量
这里是通过特定的规则(因为存储时位置也是这样计算的)去计算出该变量的存储下标,从table中取出并且判断是否相等后返回,这个Entry中value保存的就是该变量的值。
如果不存在,就初始化一个map
先判断这个线程有没有map,有的话就往map中添加这个threadlocal变量,设置一个初始值null,没有map就创建一个map最后都是返回初始化值null