ThreadLocal源码理解

  1. 什么是ThreadLocal
    threadlocal是本地线程变量,为变量在每个线程中创建副本
  2. 代码demo
public class ThreadLocalTest {
    ThreadLocal<Long> longLocal = new ThreadLocal<>();
    ThreadLocal<String> stringLocal = new ThreadLocal<>();

    public void set(){
        longLocal.set(Thread.currentThread().getId());
        stringLocal.set(Thread.currentThread().getName());
    }

    public long getLong(){
        return longLocal.get();
    }

    public String getString(){
        return stringLocal.get();
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadLocalTest test = new ThreadLocalTest();
        test.set();
        System.out.println(test.getLong());
        System.out.println(test.getString());

        Thread thread1 = new Thread(){
            public void run() {
                test.set();
                System.out.println(test.getLong());
                System.out.println(test.getString());
            };
        };
        thread1.start();
        thread1.join();
        System.out.println(test.getLong());
        System.out.println(test.getString());
    }
}

这个main方法启动的时候,至少会启动三个线程,一个是main线程一个是thread线程一个是垃圾回收器线程。
①、代码开始的第一个线程是main线程执行了test.set()方法,此时会执行方法set()继而执行longLocal.set()方法
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
先获取当前线程对象,然后根据当前线程对象thread获取其内部成员变量对象threadLocals
若不为null表示已经创建过了,就往这个threadLocalMap中存储键值对(key:当前类对象this,value:即为需要存储的值)
否则就创建threadLocalMap,通过ThreadLocal的构造方法, 把键值对传入。

②接着程序执行了System.out.println(test.getLong());语句执行了threadLocal的get()方法,获取当前线程对象的ThreadLocalMap对象
若map不为null,就从map中用当前类的对象为key,取出threadLocalMap里面的存储value的Entry数据对象(通过e.get()方法获取value返回)

总结:每个Thread对象都维护这一个ThreadLocalMap成员变量。而这个ThreadLocalMap又是ThreadLocal的内部类,所以没创建一个线程,该线程都维护着一个这样的map,map的key就是ThreadLocal类的对象,value就是要存储的值。这样就达到了,每个线程都有一个存储变量的“池子”用来存储本线程需要的变量。

今天写到这里改天在写,希望你们能看懂!

猜你喜欢

转载自blog.csdn.net/qq_27466827/article/details/81392979