美文网首页
ThreadLocal内部原理解析

ThreadLocal内部原理解析

作者: Jacksimo | 来源:发表于2017-03-25 21:04 被阅读0次

            ThreadLocal 被称为“线程内部单例”,它被用来在线程内部进行数据存取,相当于数据绑定到了某一线程,数据的作用域也仅限于当前线程。在任何一线程中访问ThreadLocal,也只是访问当前线程的ThreadLocal。

    ThreadLocal内部维护了一个静态的ThreadLocalMap类,而ThreadLocalMap类内部,又维护了一个Entry类及Entry[],我们通过ThreadLocal进行数据的存取操作,最终都是对Entry[]进行存取操作,存取的也就是Entry对象。Entry的构造方法,要传入的也就是:当前线程ThreadLocal引用和要存储的值。

    我们 new 一个ThreadLocal对象:

    ThreadLocal<String> mThreadLocal=newThreadLocal<String>();

    mThreadLocal.set("Hello word");

    (1)ThreadLocal内部set()方法实现

    public voidset(T value) {

           Thread t = Thread.currentThread();

           ThreadLocalMap map = getMap(t);

            if(map !=null)

                   map.set(this, value);

            else

                   createMap(t, value);

    }

    ThreadLocalMap构造方法之一:

    ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {

               table=newEntry[INITIAL_CAPACITY];

               int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY-1);

               table[i] =newEntry(firstKey, firstValue);

               size=1;

               setThreshold(INITIAL_CAPACITY);

    }

    首先:获取到当前Thread,然后根据当前线程拿到线程内部的ThreadLocalMap,判断ThreadLocalMap是否null,第一次是为null,然后会调用CreateMap(ThreadLocal,value)new 一个ThreadLocalMap,ThreadLocalMap的构造方法内部,先初始化一个长度为16的Entry[],接着根据ThreadLocal的hashCode值对数组初始长度16取模,获得该数据应在Entry[]中的存储位置,然后把数据存储到数组中。

    其次:如果ThreadLocalMap不为null,则会调用ThreadLocalMap的set(ThreadLocal,Value)方法,set(ThreadLocal,Value)方法内部,先根据传入的ThreadLocal的hashCode值对Entry[]长度取模,拿到该数据在Entry[]中应存储的位置,如果该位置上有Entry,则把新的值赋值给它,如果没有,则new一个新的Entry存储到Entry[]中。

    (2)ThreadLocal的get()方法内部实现

    public T get() {

            Thread t = Thread.currentThread();

            ThreadLocalMap map = getMap(t);

             if(map !=null) {

                        ThreadLocalMap.Entry e = map.getEntry(this);

                        if(e !=null)

                        return  (T)e.value;

            }

    return  setInitialValue();

    }

    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;

    }

    protected T initialValue() {

    return null;

    }

    首先:获取当前线程,获取当前线程内部的ThreadLocalMap,判断ThreadLocalMap是否null,第一次是为null,然后调用setInitialValue(),setInitialValue()方法内部,先调用initialValue()返回一个null值,接着会调用createMap(TheadLocal,Value)初始化一个ThreadLocalMap,所以第一次获取到ThreadLocal内部的数据是为null的。

    其次:如果ThreadLocalMap不为null,就会调用ThreadLocalMap内部的getEntry(),genEntry()先根据传入的ThreadLocal的hashCode值对Entry[]数组长度取模,获得该数据在数组中的位置,然后拿到该数据。

    相关文章

      网友评论

          本文标题:ThreadLocal内部原理解析

          本文链接:https://www.haomeiwen.com/subject/ciycottx.html