ThreadLocal的源码解析

涉及到类:Thread、ThreadLocal、ThreadLocalMap(ThreadLocal的内部类)

含义:这些变量与普通变量不同,每个访问一个线程(通过其get或set方法)的线程都有其自己的,独立初始化的变量副本。 ThreadLocal实例通常是希望将状态与线程关联的类中的私有静态字段(例如,用户ID或交易ID)

例子:

private static class ThreadA extends Thread {
        @Override
        public void run() {

            //  每个访问一个线程(通过其get或set方法)的线程都有其自己的,独立初始化的变量副本
            ThreadLocal<Integer> threadlocal = new ThreadLocal<Integer>();
            threadlocal.set(1);

            threadlocal.get();
        }
    }

源码解析如下:(每一个Thread维护着一个ThreadLocalMap)

class Thread{   
    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

    /*
     * InheritableThreadLocal values pertaining to this thread. This map is
     * maintained by the InheritableThreadLocal class.
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; // 用于继承
}

当ThreadLocal的set方法

class ThreadLocal{   
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        // 如果THreadLocalMap为空,就新建一个
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
}
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals; // 获得当前线程维护的ThreadLocalMap
    }
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

ThreadLocalMap的key是对应的ThreadLocal<>

class ThreadLocal{  
   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;
            }
        }
        // 如果没有ThreadLocalMap的初始值 
        return setInitialValue();
    }
}

与线程生命状态相关的体现

class Thread{
    private void exit() {
        if (group != null) {
            group.threadTerminated(this);
            group = null;
        }
        /* Aggressively null out all reference fields: see bug 4006245 */
        target = null;
        /* Speed the release of some of these resources */
        threadLocals = null;  // 退出时销毁
        inheritableThreadLocals = null;
        inheritedAccessControlContext = null;
        blocker = null;
        uncaughtExceptionHandler = null;
    }
}

ThreadLocal使用场景:

(1)使用实例:Handler、looper

class Looper{   
    
    // 获得每个线程独立的looper 
    private ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
 
    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        // 新建looper其中维护着queue管理Messege,用于线程的通信
        sThreadLocal.set(new Looper(quitAllowed));
    }

    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }
}

(2)可用于静态方法在多线程中的调用,获得专属当前的线程的内存区域(变量),这个是静态变量无法实现,因为静态变量无法区分线程(Lopper实现方式一致)

public class Text {

    private final static ThreadLocal<Integer> local = new ThreadLocal<Integer>(){
        protected Integer initialValue() {
            return 1;
        }
    };

    public static int A() {
        
        // 每一个线程都会有独立的一份变量
        Integer integer = local.get();
        local.set(++integer);
        return integer;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章