阅读了JDK的Thread、ThreadLocal源代码之后,有几点设计心得:
- Thread类,有一个ThreadLocal.ThreadLocalMap类型的成员变量
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
这个变量不是static的,每个线程对象都会有自己的threadLocals,不会产生数据共享问题,因此不会导致线程安全问题;该变量初始值是null,这是因为并不是所有的线程都需要考虑线程安全问题,这样可以减少不必要对象的创建
- ThreadLocal的set方法,为什么key是this
public void set(T value)
{
// 获取进入ThreadLocal的当前线程
Thread t = Thread.currentThread();
// ThreadLocalMap是ThreadLocal的内部类,对使用者是透明的
// 如果第一次进入set,map值是null,因为Thread内部将其初始值设为null
ThreadLocalMap map = getMap(t);
if (map != null)
{
map.set(this,value);
} else
{
createMap(t, value);
}
}
首先每个Thread对象都只会有1个ThreadLocal.ThreadLocalMap成员变量,但是一个线程使用多少个ThreadLocal则是不确定的。Thread每次使用ThreadLocal的时候,都应该是相互独立的,而且key不能是重复的。由于java对象的内存地址的唯一性,所以使用ThreadLocal作为key,很安全,不会重复。
如果不这样设计,难以满足下面代码的使用
public class Test
{
private ThreadLocal<String> StringLocal = new ThreadLocal<String>();
private ThreadLocal<Integer> intLocal = new ThreadLocal<Integer>();
// 1个方法使用2个ThreadLocal对象进行值存储
public void setValue(String strVal, int intVal)
{
StringLocal.set(strVal);
intLocal.set(intVal);
}
}