谈谈ThreadLocal

做安卓的同学想必,一提到ThreadLocal会首先想到安卓中大名鼎鼎的handler消息机制,或许也大概是从了解handler消息机制开始接触并了解的ThreadLocal。

#ThreadLocal的特点及原理#

ThreadLocal的作用是保存线程内的共享变量,不同线程间不能互相访问。

ThreadLocal tl = new ThreadLocal<>();
tl.set("天王盖地虎");

构造方法:

    /**
     * Creates a thread local variable.
     * @see #withInitial(java.util.function.Supplier)
     */
    public ThreadLocal() {
    }

tl.set("xxx");方法

     /**
     * 给当前线程的threadlocal变量的拷贝设置指定的value值,大多数子类
     * 不需要覆写这个方法,通过initialValue方法设置就可以了
     *
     * @param value 给当前线程的这个thread local的拷贝设置的值
     */
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

每个线程中都有一个ThreadLocalMap变量
Thread.java#188

    /* 属于这个Thread的ThreadLocalMap变量,由ThreadLocal类维护 */
    ThreadLocal.ThreadLocalMap threadLocals = null;

set方法中的getMap返回当前线程的ThreadLocalMap变量


        /**
         * The entries in this hash map extend WeakReference, using
         * its main ref field as the key (which is always a
         * ThreadLocal object).  Note that null keys (i.e. entry.get()
         * == null) mean that the key is no longer referenced, so the
         * entry can be expunged from table.  Such entries are referred to
         * as "stale entries" in the code that follows.
         */
        static class Entry extends WeakReference> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal k, Object v) {
                super(k);
                value = v;
            }
        }

Entry继承自WeakReference,扩展出一个Object变量,成为了键值对(ThreadLocal, Object)的弱引用,很巧妙!

ThreadLocalMap是定义在ThreadLocal中的一个静态类,用来维护一个map结构,保存ThreadLocal和value的映射关系,这个映射关系就是Entry。

INITIAL_CAPACITY = 16;// 初始容量
private Entry[] table; // 一个Entry的table,可以扩容,值需要为2的幂
private int size = 0; // 这个table的大小
private int threshold; // 容量的阈值,用来判断是否需要扩容

你可能感兴趣的:(谈谈ThreadLocal)