什么是ThreadLocal
我们来看看作者Doug Lea是怎么说的,下面是jdk7.x里面ThreadLocal注释
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g.a user ID or Transaction ID).
each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist)
也就是说这个类给线程提供了一个本地变量,这个变量是该线程自己拥有的。在该线程存活和ThreadLocal实例能访问的时候,保存了对这个变量副本的引用.当线程消失的时候,所有的本地实例都会被GC。并且建议我们ThreadLocal最好是 private static 修饰的成员
和Thread的关系
假设我们要设计一个和线程绑定的变量,我们会怎么做呢?很常见的一个思路就是把Thread和变量放在一个Map
/**
* Sets the current thread's copy of this thread-local variable
* to the specified value. Most subclasses will have no need to
* override this method, relying solely on the {@link #initialValue}
* method to set the values of thread-locals.
*
* @param value the value to be stored in the current thread's copy of this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();
//通过当前线程得到一个ThreadLocalMap
ThreadLocalMap map = getMap(t);
//map存在,则把value放入该ThreadLocalMap中
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
然后,看看getMap方法做了些什么
/**
* Get the map associated with a ThreadLocal. Overridden in
* InheritableThreadLocal.
*
* @param t the current thread
* @return the map
*/
ThreadLocalMap getMap(Thread t) {
//返回Thread的一个成员变量
return t.threadLocals;
}
原来是把ThreadLocalMap和Thread绑定起来了,Thread类中有一个ThreadLocalMap为null的变量,那我们现在回到ThreadLocalMap来看,在我们Thread返回的引用来看,如果map为null的情况下,调用了createMap方法.这就为我们的Thread创建了一个能保存在本地线程的map.下面是Thread里面的字段
/* ThreadLocal values pertaining to this thread. This map is maintained by the ThreadLocal class. */
//ThreadLocal帮助Thread赋值了该字段
ThreadLocal.ThreadLocalMap threadLocals =