Java并发编程-ThreadLocal原理

大半夜的研究了一下ThreadLocal,头脑不是特别清醒,如果疑问,欢迎探讨啊。
核心
Thread 类中有  ThreadLocal.ThreadLocalMap threadLocals = null; 变量

ThreadLocalMap类主要代码:
一个弱引用的内部类
static class Entry extends WeakReference<ThreadLocal> {
            /** The value associated with this ThreadLocal. */
      Object value;

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

构造方法
 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);
}

private Entry getEntry(ThreadLocal key) {
      int i = key.threadLocalHashCode & (table.length - 1);
      Entry e = table[i];
      if (e != null && e.get() == key)
          return e;
      else
      return getEntryAfterMiss(key, i, e);
 }

ThreadLocal 类中
再看一下如何往ThreadLocal中存取数据:
 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();
    }

 public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
}

void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
}

在第一次存数据的时候,由于当前线程的threadLocals为null,所以会根据当前线程的ThreadLocal对象【该对象一般设计为静态常量】,以及实际要存放的值,创建一个ThreadLocalMap,并将其赋给Thread类中的threadLocals变量,也就是将Thread类中的threadLocals变量给初始化了。

在取数据的时候,也是要根据当前线程取得自己的ThreadLocalMap,然后通过ThreadLocal对象【跟创建时使用的对象是同一个】取得相应的值。


几点说明:
1、在使用过程中,最核心的应该是ThreadLocalMap。随线程的增减,变化的也是ThreadLocalMap。
2、ThreadLocalMap中数据的存放是以程序中声明的Threadlocal对象为key,实际需要值为value进行存放的。一般Key都是常量的,这也是为什么程序中ThreadLocal对象一般声明为静态常量的原因。
3、如果Threadlocal不设计为静态常量,那么会有什么后果呢?
对每个线程都会创建的是ThreadLocalMap对象。每个程序中定义的ThreadLocal对象对应着ThreadLocalMap对象的key。如果Threadlocal不为常量,那么服务器在运行过程中,ThreadLocal对象的数量为应用中存在的线程数【假如一个线程对应一个Threadlocal】。

讨论:
既然在使用过程中起核心作用的是ThreadLocalMap,那么为什么不直接在Thread类中实现这个Map呢?
个人观点是从软件设计的角度来考虑的。因为如果写到Thread里面,那么Thread中的功能太多,造成功能的耦合性太强,简单说就是 Thread本身就应该只有 start(),stop(),run()等自己的行为,而不应该包含其他不属于它的工作。


写的有点乱,没有好好的组织一下思路。




你可能感兴趣的:(threadLocal)