TreadLocal原理及其使用分析

       对于TreadLocal,是有听说的,只是一直没有对它进行很全面的了解,最近因为有机会要用到,所以就找了很多文章看了下,也看了TreadLocal类的源码,总的感觉很多博客的文章说的有点模糊(可能是对于自己,理解不了),这里想总结一下,可能会有其他博文的一些内容。

分析:

      (1) ThreadLocal 不是用来解决共享对象的多线程访问问题的,这一点很关键!假设一个变量声明了一个变量为ThreadLocal 类型的,那么这个变量是在每个线程中保留一个副本,而这个副本是保留在线程自身ThreadLocalMap中;

   (2)ThreadLocal和Thread密切联系,每个从Tread类继承的类的对象中都有个ThreadLocalMap,而这个ThreadLocalMap对象有一个entry数组,保存属于这个对象的threadlocal变量,也就是说一个thread之类对象可以使用很多treadlocal变量,而treadlocal变量在对象中保存的方式是键值对的方式,也就是通过entry结构保存,在键值对中,key为threadlocal变量的引用、值为threadlocal变量在线程中的取值。下面逐步分析。

     在Thread.java源码中有这么一句:

                          ThreadLocal.ThreadLocalMap threadLocals = null;
     说明每个Thread对象都有一个ThreadLocal.ThreadLocalMap成员变量。

     而T hreadLocal.ThreadLocalMap是一个ThreadLocal类的静态内部类。如下所示:

    ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {
                  table = new Entry[INITIAL_CAPACITY];
                  int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
                  table[i] = new Entry(firstKey, firstValue);
                  size = 1;
                  setThreshold(INITIAL_CAPACITY);
               }
      当在ThreadLocal中进行设值的时候:
     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;
                 }
      首先获取当前线程的引用,然后获取当前线程的ThreadLocal.ThreadLocalMap对象(注意:t.threadLocals变量就是ThreadLocal.ThreadLocalMap的变量),如果该对象为空就创建一个,如下所示:
        void createMap(Thread t, T firstValue) {
            t.threadLocals = new ThreadLocalMap(this, firstValue);
         }

可以看出:

             注意上面的这个this变量就是ThreadLocal的引用,这对于每个线程都是相同的,线程之间不同是ThreadLocal变量在线程中的取值。

              每个线程各自有一个ThreadLocal.ThreadLocalMap对象,这个对象保存着ThreadLocal引用为key的值,ThreadLocal变量在线程中的取值为值。

              如果执行get()、set()方法,是对前线程中的ThreadLocalMap中对应的ThreadLocal对象的取值就行操作。

              如果你新建一个ThreadLocal的对象,这个对象还是保存在每个线程同一个ThreadLocal.ThreadLocalMap对象之中,因为一个线程只有一个ThreadLocal.ThreadLocalMap对象,这个对象是在第一个ThreadLocal第一次设值的时候进行创建,如上所述的createMap方法。


进一步:

  ThreadLocalMap是Thread和ThreadLocal之间的桥梁,每个Thread子类对象都有一个ThreadLocalMap,ThreadLocalMap是ThreadLocal的静态内

部类,而我们在真正使用的时候用到了ThreadLocal和Thread,ThreadLocalMap起到了很好的桥梁作用。

 

如果有兴趣可以进一步参看http://www.iteye.com/topic/103804

你可能感兴趣的:(TreadLocal原理及其使用分析)