首页 > 代码库 > ThreadLocal

ThreadLocal

public class ThreadLocal<T> {      /**      * ThreadLocals rely on per-thread hash maps attached to each thread      * (Thread.threadLocals and inheritableThreadLocals).  The ThreadLocal      * objects act as keys, searched via threadLocalHashCode.  This is a      * custom hash code (useful only within ThreadLocalMaps) that eliminates      * collisions in the common case where consecutively constructed      * ThreadLocals are used by the same threads, while remaining well-behaved      * in less common cases.      */      private final int threadLocalHashCode = nextHashCode();        /**      * The next hash code to be given out. Accessed only by like-named method.      */      private static int nextHashCode = 0;        /**      * The difference between successively generated hash codes - turns      * implicit sequential thread-local IDs into near-optimally spread      * multiplicative hash values for power-of-two-sized tables.      */      private static final int HASH_INCREMENT = 0x61c88647;        /**      * Compute the next hash code. The static synchronization used here      * should not be a performance bottleneck. When ThreadLocals are      * generated in different threads at a fast enough rate to regularly      * contend on this lock, memory contention is by far a more serious      * problem than lock contention.      */      private static synchronized int nextHashCode() {          int h = nextHashCode;          nextHashCode = h + HASH_INCREMENT;          return h;      }        /**      * Creates a thread local variable.      */      public ThreadLocal() {      }        /**      * Returns the value in the current thread‘s copy of this thread-local      * variable.  Creates and initializes the copy if this is the first time      * the thread has called this method.      *      * @return the current thread‘s value of this thread-local      */      public T get() {          Thread t = Thread.currentThread();          ThreadLocalMap map = getMap(t);          if (map != null)              return (T)map.get(this);            // Maps are constructed lazily.  if the map for this thread          // doesn‘t exist, create it, with this ThreadLocal and its          // initial value as its only entry.          T value =http://www.mamicode.com/ initialValue();          createMap(t, value);          return value;      }        /**      * Sets the current thread‘s copy of this thread-local variable      * to the specified value.  Many applications will have no need for      * this functionality, relying solely on the {@link #initialValue}      * method to set the values of thread-locals.      *      * @param value the value to be stored in the current threads‘ 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);      }        /**      * 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;      }        /**      * 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      * @param map the map to store.      */      void createMap(Thread t, T firstValue) {          t.threadLocals = new ThreadLocalMap(this, firstValue);      }        .......        /**      * ThreadLocalMap is a customized hash map suitable only for      * maintaining thread local values. No operations are exported      * outside of the ThreadLocal class. The class is package private to      * allow declaration of fields in class Thread.  To help deal with      * very large and long-lived usages, the hash table entries use      * WeakReferences for keys. However, since reference queues are not      * used, stale entries are guaranteed to be removed only when      * the table starts running out of space.      */      static class ThreadLocalMap {        ........        }    }

在Eclipse中查看JDK类库的源代码设置: 

1.点 “window”-> "Preferences" -> "Java" -> "Installed JRES"

2.此时"Installed JRES"右边是列表窗格,列出了系统中的 JRE 环境,选择你的JRE,然后点边上的 "Edit...", 会出现一个窗口(Edit JRE)

3.选中rt.jar文件的这一项:“c:\program files\java\jre_1.5.0_06\lib\rt.jar” 
点 左边的“+” 号展开它,

4.展开后,可以看到“Source Attachment:(none)”,点这一项,点右边的按钮“Source Attachment...”, 选择你的JDK目录下的 “src.zip”文件

5.一路点"ok",结束。

dt.jar是关于运行环境的类库,主要是swing的包 
tools.jar是关于一些工具的类库 
rt.jar包含了jdk的基础类库,也就是你在java doc里面看到的所有的类的class文件

 

解读

ThreadLocal部分源码如上, 每个Thread中有个ThreadLocalMap, 合并代码, 其实存放的Map也就是Thread.currentThread().threadLocals,然后把ThreadLocal实例作为Key值,把对象放入。

疑问: 如果不改写ThreadLocal, 使用原生态的get(), set()方法的话, 我认为一个ThreadLocalMap里只存一个对象, 因为ThreadLocal实例作为Key值只有一个, 我觉得有点浪费。