天天看点

ThreadLocal源码解析前言ThreadLocal的源码

@[toc]

前言

ThreadLocal的源码

本节 我们详细了解ThreadLocal的源码,让大家更为了解ThreadLocal

ThreadLocalMap

ThreadLocal源码解析前言ThreadLocal的源码

ThreadLocal中的嵌套内部类ThreadLocalMap,这个类本质上是一个map,和HashMap之类的实现相似,依然是key-value的形式,其中有一个内部类Entry,其中key可以看做是ThreadLocal实例,但是其本质是持有ThreadLocal实例的弱引用

ThreadLocal源码解析前言ThreadLocal的源码

ThreadlocalMap 会发现他是ThreadLocal 的一个内部类,

会发现他有一个Entry

**Entry继承WeakReference,使用弱引用,可以将ThreadLocal对象的生命周期和线程生命周期解绑,持有对ThreadLocal的弱引用,可以使得ThreadLocal在没有其他强引用的时候被回收掉,这样可以避免因为线程得不到销毁导致ThreadLocal对象无法被回收。并且

他是 以key value 形式的Entry **

有兴趣的同学可以打开 底层源码看下具体实现

initialValue

ThreadLocal源码解析前言ThreadLocal的源码

initialValue ThreadLocal初始化的方法,默认为 null ,可以重写

ThreadLocal源码解析前言ThreadLocal的源码

get 方法

会发现他把 Thread.currentThread(); 传到 getMap() 方法中,

ThreadLocal源码解析前言ThreadLocal的源码

调用Thread 类 中定义的 Threadlocal.ThreadlocalMap() 返回一个map

判断当前线程的map是否存在,不为空, 获取当前Entry 实例,

判断这个键值对是否为空

如果不是空,就返回对应的value值

此处是当前线程的map不存在,返回setInitialValue,为空返回初始化值

这里有个非常重要的知识,initialValue 是使用懒加载 ,只有调用 get 的时候才会 使用initialValue 方法,在 new ThreadLocal 中是不会初始化的

private T setInitialValue() {
    //获取初始化值,默认为null(如果没有子类进行覆盖)
    T value = initialValue();
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    //不为空不用再初始化,直接调用set操作设值
    if (map != null)
        map.set(this, value);
    else
        //第一次初始化,createMap在上面介绍set()的时候有介绍过。
        createMap(t, value);
    return value;
}
           

接下来我们看下 set的方法

set方法

ThreadLocal源码解析前言ThreadLocal的源码

判断当前线程的map是否存在,如果ThreadLocal中有这个map,就把当前类和对应的值传进去

如果没有这个map,就新建一个t线程的ThreadLocalMap,并将value值传进去

remove方法

ThreadLocal源码解析前言ThreadLocal的源码

remove方法就比较简单了

继续阅读