ThreadLocal

48 阅读1分钟
public class Main {
    static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(()->{
            System.out.println(threadLocal.get());
            threadLocal.set(0);
            System.out.println(threadLocal.get());
            threadLocal.remove();
        });
        Thread t2=new Thread(()->{
            System.out.println(threadLocal.get());
            threadLocal.set(1);
            System.out.println(threadLocal.get());
            threadLocal.remove();
        });
        t1.start();
        t1.join();
        t2.start();
    }
}
null
0
null
1

ThreadLocal,各个线程独立的全局变量。

如果一个处理流程由多个函数组成,每个函数都需要一个变量,那么把这个变量提出来作为全局变量会更方便。
当这个处理流程被多个线程处理,比如一个controller接口,每接受到一个请求都会开一个线程,这些线程的流程代码是一样的,那么刚才的全局变量在多线程情况下就会有问题,应该保证每个线程的全局变量独立,这就是ThreadLocal。

ThreadLocal.png

每个线程里面都有一个ThreadLocalMap,ThreadLocalMap是一个Entry的数组,Entry是k-v键值对,其中k是ThreadLocal对象,v是set()方法设置的对应值。
get,set方法都会先获取当前线程对象,从而获取该线程的ThreadLocalMap。
Entry的k是弱引用,v是强引用,如果线程结束k只能存活至下一次GC,但v会一直存在,所以在线程结束前需要手动执行remove方法。