ThreadLocal深入浅出

ThreadLocal深入浅出

    一、分析ThreadLocal源码

    ThreadLocal的核心方法一共就几个,get(),set()等等,我们由get()开始,一边分析其源码,一边揭开ThreadLocal的面纱。

    先看看JDK7中的get()源码:

    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }
    当调用get()方法时,首先会获取当前线程,然后调用getMap方法获取一个ThreadLocalMap对象,我们来看看ThreadLocalMap的源码:
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }
    很显然,getMap(Thread t)方法用于返回线程的ThreadLocalMap类型成员变量,我们来看看Thread类源码:
ThreadLocal.ThreadLocalMap threadLocals = null;
    成员变量是一个初始为null的值,ThreadLocalMap是ThreadLocal的一个内部静态类。好了,再回到get()方法,以下代码说明,当ThreadLocalMap对象及其Entry对象皆不为空的时候,返回Entry的value,否则,返回setInitialValue()返回值:
if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();

    Entry是一个键值对应的关系,维护着ThreadLocal对象和Object对象之间的关系。

    setInitialValue()的源码如下:

private T setInitialValue() {
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }

    代码十分简单,新建一个value,当当前线程ThreadLocalMap成员变量为空,则创建map,如果不为空,在map中插入this和value的对应关系,同时返回value。initialValue()是一个protected修饰的方法,用于设置value的默认值,可以重写。

    至此就够了,由上文我们可以知道,关键概念是ThreadLocalMap对象,为Thread的成员变量,维护着ThreadLocal对象和Object对象的键值对应关系,可见,一个Thread可以和多个ThreadLocal对象对应,他们之间的关系图如下:




    因为,ThreadLocal是弱引用,如果一直没有被引用,势必会被GC回收,此时,Thread中ThreadLocalMap的Entry的key就为空,如果Thread迟迟不结束,value对应的对象就一直不会被释放,造成内存泄露。

猜你喜欢

转载自blog.csdn.net/that_is_cool/article/details/80183928