码迷,mamicode.com
首页 > 其他好文 > 详细

ThreadLocal源码学习

时间:2014-08-19 22:16:45      阅读:355      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   java   使用   os   io   

ThreadLocal,线程本地化对象,在多线程环境中,使用ThreadLocal对象来维护变量时,ThreadLocal为每个使用该变量的线程维护一个独立的线程副本。

ThreadLocal.java源文件内容为:

  1 /**
  2   * ThreadLocal内部包含一个用数组实现的哈希表,用来存储对应到每个线程的局部对象的值
  3   * 其中,ThreadLocal对象担当key,实际通过threadLocalHashCode值来进行检索
  4   */
  5 public class ThreadLocal<T> {
  6     //其中 T 类型代表的是被多个线程访问的局部变量类型 
 10     private final int threadLocalHashCode = nextHashCode(); 
 11     /** 
 12     * Returns the current thread‘s "initial value" for this 
 13     * thread-local variable. This method will be invoked the first 
 14     * time a thread accesses the variable with the {@link #get} 
 15     * method, unless the thread previously invoked the {@link #set} 
 16     * method, in which case the <tt>initialValue</tt> method will not 
 17     * be invoked for the thread. Normally, this method is invoked at 
 18     * most once per thread, but it may be invoked again in case of 
 19     * subsequent invocations of {@link #remove} followed by {@link #get}. 
 20     * * <p>This implementation simply returns <tt>null</tt>; if the 
 21     * programmer desires thread-local variables to have an initial 
 22     * value other than <tt>null</tt>, <tt>ThreadLocal</tt> must be 
 23     * subclassed, and this method overridden. Typically, an 
 24     * anonymous inner class will be used. 
 25     * * @return the initial value for this thread-local(返回当前线程局部对象的初始值) 
 26     */ 
 27     protected T initialValue() { 
 28         //protected成员,期望被子类继承 
 29         return null; 
 30     } 
 31     /** 
 32     * 返回在当前线程中的线程局部对象的值, 
 33     * 若线程局部对象对于当前线程没有值,则被初始化微 initialValue方法的返回值 
 34     */ 
 35     public T get() { 
 36         Thread t = Thread.currentThread(); 
 37         ThreadLocalMap map = getMap(t); 
 38         if (map != null) { 
 39             ThreadLocalMap.Entry e = map.getEntry(this); 
 40             if (e != null) 
 41                 return (T)e.value; 
 42         } 
 43 
 44             return setInitialValue(); 
 45     } 
 46 
 47     /** 
 48     * Sets the current thread‘s copy of this thread-local variable 
 49     * to the specified value. Most subclasses will have no need to 
 50     * override this method, relying solely on the method to set the values of thread-locals. 
 51     */ 
 52     public void set(T value) { 
 53         Thread t = Thread.currentThread(); 
 54         ThreadLocalMap map = getMap(t); 
 55         if (map != null) 
 56             //以当前线程对象为key,设置当前局部对象的值
 57             map.set(this, value); 
 58         else 
 59             createMap(t, value); 
 60     } 
 61 
 62     /** 
 63     * Removes the current thread‘s value for this thread-local 
 64     * variable. If this thread-local variable is subsequently 
 65     * {@linkplain #get read} by the current thread, its value will be 
 66     * reinitialized by invoking its {@link #initialValue} method, 
 67     * unless its value is {@linkplain #set set} by the current thread 
 68     * in the interim. This may result in multiple invocations of the 
 69     * <tt>initialValue</tt> method in the current thread. 
 70     */ 
 71     public void remove() { 
 72         ThreadLocalMap m = getMap(Thread.currentThread()); 
 73         if (m != null) 
 74             //从ThreadLocalMap中移除对象
 75             m.remove(this); 
 76     } 
 77 
 78     /** 
 79     * Get the map associated with a ThreadLocal. Overridden in 
 80     * InheritableThreadLocal. 
 81     * * @param t the current thread 
 82     * @return the map 
 83     */ 
 84     ThreadLocalMap getMap(Thread t) { 
 85         //返回当前Threadlocal相关的ThreadLocalMap对象 
 86         return t.threadLocals; 
 87     } 
 88 
 89     /** 
 90     * Create the map associated with a ThreadLocal. Overridden in 
 91     * InheritableThreadLocal. 
 92     * * @param t the current thread 
 93     * @param firstValue value for the initial entry of the map 
 94     * @param map the map to store. 
 95     */ 
 96     void createMap(Thread t, T firstValue) { 
 97         t.threadLocals = new ThreadLocalMap(this, firstValue); //为当前线程创建关联的ThreadLocalMap对象 
 98     } 
 99 
100     //ThreadLocalMap是一个定制的只能用来存储线程局部对象的哈希映射 
101     //使用弱引用来当做key,只有当表空间不够时,旧的对象才会被移除 
102     static class ThreadLocalMap { 
103         //ThreadLocalMap的内部数组的元素类型:使用对ThreadLocal的弱引用类型来作为元素类型 
104         static class Entry extends WeakReference<ThreadLocal> { 
105         /** 
106         * The value associated with this ThreadLocal. 
107         */ 
108         Object value; 
109 
110         Entry(ThreadLocal k, Object v) { 
111             super(k); 
112             value = v; 
113         } 
114     } 
115 
116     //哈希表的初始大小 
117     private static final int INITIAL_CAPACITY = 16; 
118 
119     /** 
120     * 用于存储ThreadLocal弱引用的数组 
121     */ 
122     private Entry[] table; 
123 
124     //ThreadLocalMap使用延迟初始化,当我们需要向ThreadLocalMap中放元素时,才会初始化它 
125     ThreadLocalMap(ThreadLocal firstKey, Object firstValue) { 
126         table = new Entry[INITIAL_CAPACITY]; 
127         int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); 
128         table[i] = new Entry(firstKey, firstValue); //初始时,使用ThreadLocal.threadLocalHashCode作为哈希表的哈希值 size = 1; 
129 
130         //设定ThreadLocalMap中元素个数 
131         setThreshold(INITIAL_CAPACITY); 
132     } 
133 
134     /** 
135     * Set the value associated with key. 
136     * * @param key the thread local object 
137     * @param value the value to be set 
138     */ 
139     private void set(ThreadLocal key, Object value) { 
140         // We don‘t use a fast path as with get() because it is at 
141         // least as common to use set() to create new entries as 
142         // it is to replace existing ones, in which case, a fast 
143         // path would fail more often than not. 
144         Entry[] tab = table; 
145         int len = tab.length; 
146         int i = key.threadLocalHashCode & (len-1); 
147         for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { 
148             ThreadLocal k = e.get(); 
149             if (k == key) { 
150                 e.value = value; 
151                 return; 
152             } 
153 
154             if (k == null) { 
155                 replaceStaleEntry(key, value, i); 
156                 return;
157             } 
158         } 
159 
160         tab[i] = new Entry(key, value); 
161         int sz = ++size; 
162         if (!cleanSomeSlots(i, sz) && sz >= threshold) 
163             rehash(); 
164     } 
165 
166     /** 
167     * Remove the entry for key. 
168     */ 
169     private void remove(ThreadLocal key) { 
170         Entry[] tab = table; 
171         int len = tab.length; 
172         int i = key.threadLocalHashCode & (len-1); 
173         for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { 
174             if (e.get() == key) { 
175                 e.clear(); 
176                 expungeStaleEntry(i); 
177                 return; 
178             } 
179         } 
180     } 
181 }

 

ThreadLocal源码学习,布布扣,bubuko.com

ThreadLocal源码学习

标签:des   style   blog   color   java   使用   os   io   

原文地址:http://www.cnblogs.com/-crazysnail/p/3923093.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!