Java ThreadLocal 是如何发挥作用的

Java ThreadLocal 是如何发挥作用的。

首先插入一个ThreadLocal的使用场景以及用法的链接,这个链接里讲的很通畅。
看完之后我们分析下源码:

以下源码来自JDK1.8
Thread.java源码

public
class Thread implements Runnable {
    //...
    //Thread中包含了一个ThreadLocal.ThreadLocalMap局部变量。ThreadLocalMap是ThreadLocal的内部类,维护了一个Hash map
    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

    //..

    //与threadLocals变量相关的方法有以下:

    //该方法就是用于在线程退出时,清理线程资源的。可以看到将threadLocals置为了null
    /**
     * This method is called by the system to give a Thread
     * a chance to clean up before it actually exits.
     */
    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.java部分源码

//与threadLocals变量相关的方法有以下:


    /**
     * Get the map associated with a ThreadLocal. Overridden in
     * InheritableThreadLocal.
     *
     * @param  t the current thread
     * @return the map
     */
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;   //返回线程t中的成员变量threadLocals
    }

     /**
     * Create the map associated with a ThreadLocal. Overridden in
     * InheritableThreadLocal.
     *
     * @param t the current thread
     * @param firstValue value for the initial entry of the map
     */
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }


//ThreadLocal的get、set方法
     /**
     * Returns the value in the current thread's copy of this
     * thread-local variable.  If the variable has no value for the
     * current thread, it is first initialized to the value returned
     * by an invocation of the {@link #initialValue} method.
     *
     * @return the current thread's value of this thread-local
     */
    public T get() {
        Thread t = Thread.currentThread();//从这里可以看到,如果在一个线程中调用了该方法之后,会获取到该线程(当前线程)
        ThreadLocalMap map = getMap(t);  //并作为变量传入getMap()方法中。所以最终得的map便是当前线程中的threadLocals。
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this); //ThreadLocalMap中key是ThreadLocal变量(this),value是
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();  //该方法设置当前线程的ThreadLocalMap中key为this,value为null。如果ThreadLocalMap为空则新建然后再设置
    }

     /**
     * Sets the current thread's copy of this thread-local variable
     * to the specified value.  Most subclasses will have no need to
     * override this method, relying solely on the {@link #initialValue}
     * method to set the values of thread-locals.
     *
     * @param value the value to be stored in the current thread's copy of
     *        this 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来保存多个ThreadLocal变量。key就是ThreadLocal变量。每次set/get操作都是对应到当前线程的map上。达到了隔离的效果。当然了ThreadLocalMap并不是implement Map的,其内部也不是用HashMap实现的,是另外一种hash算法。

猜你喜欢

转载自blog.csdn.net/zhaominpro/article/details/79391282