ThreadLocal源码分析详解

引言

由于太久没有复习过ThreadLocal啦,有点记忆丢失了,正好出一篇来记录一下【绝绝子ing】。

前置知识点

首先,ThreadLocal有一个静态内部类ThreadLocalMap,ThreadLocalMap就是用来保存线程内的共享变量的;然后,在Thread中就有一个ThreadLocal.ThreadLocalMap变量;所以呢,线程内共享就是把数据保存在自己的Thread的ThreadLocal.ThreadLocalMap中啦。

ThreadLocal

ThreadLocal源码还是挺简单的,也很容易就看明白了

//初始化数据。延迟调用方法,在第一次调用get或set时才执行,在每个线程最多调用一次。默认返回null。
protected T initialValue() 
 //获取当前线程的变量
public T get() 
//设置当前线程的变量
public void set(T value) 
 //删除当前线程的变量
public void remove() 

下面按顺序开始吧。。。

  1. protected T initialValue()
protected T initialValue() {
	return null;
}

惊不惊喜,意不意外,还没开始就结束了,不用多说啦,就返回一个null。

  1. public T get()
public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}
ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}
// 这个方法跟下面的set差不多了,不敢说十分相似,只能说是一模一样
 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;
 }

调用get()方法,先获取到当前的线程对象Thread t,然后再去获取线程t的ThreadLocalMap,以当前的ThreadLocal对象为key,从map中获取变量,如果map中有变量,就返回变量,否则,就调用setInitialValue(),给map存一个null,并将这个null返回。

  1. public void set(T value)
public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}
void createMap(Thread t, T firstValue) {
    t.threadLocals = new ThreadLocalMap(this, firstValue);
}

获取当前线程t,再获取t的ThreadLocalMap,如果map不是null,就把value保存进去,其中key是当前ThreadLocal对象的引用this,value就是我们传进来的value了,如果map是null的话,就给线程t创建(new)一个ThreadLocalMap再把值存进去。

  1. public void remove()
public void remove() {
    ThreadLocalMap m = getMap(Thread.currentThread());
    if (m != null)
        m.remove(this);
}

也还是那个流程,获取当前线程t,再获取t的ThreadLocalMap,不是null就将变量删除了。key还是当前的ThreadLocal对象啦。


版权声明:本文为qq_47768542原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。