ThreadLocal

ThreadLocal

1.ThreadLocal是什么

ThreadLocal 是一个创建线程局部变量的类
通常我们创建的变量是可以被任何一个线程访问的,而使用 ThreadLocal 创建的变量只能被当前线程访问,其他线程无法访问。

2.ThreadLocal是如何确保只有当前线程可以访问

我们先来分析一下ThreadLocal里面最重要的两个函数,get()set()两个函数。

   public T get() {
        //获取当前线程
        Thread t = Thread.currentThread();
        //利用当前线程t来获取当前线程中的 threadLocals 变量
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            //利用当前threadlocal作为key来获取 ThreadLocalMap.Entry,其中就有保存的value
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
    


  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 getMap(Thread t) {
        return t.threadLocals;
    }

get()set()两个函数,不难发现,在给ThreadLocal去set值或者get值的时候都会先获取当前线程,然后使用线程去调用getMap(thread),getMap返回的就是线程thread的成员变量threadLocals。所以这样就保证了threadLocal的访问,一定是只能访问或修改当前线程的值,这就保障了这个变量是线程的局部变量。

ThreadLocal.png

ThreadLocalMap是什么

ThreadLocalMap是ThreadLocal的内部类。


   static class 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<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
         private Entry[] table;
    }
    

从源码可以看出来ThreadLocalMap中有一个数组table,数组里面是继承自弱引用的Entry。弱引用的使用也是为了当出现异常情况,比如死循环的时候内存能得到回收。Entry里面就保存了真实的白娘value,并且以threadlocal作为key。所以相同类型的threadLocal只能在线程中关联一个实例。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容