标签:
1.Thread类中有一个叫 threadLocals的变量
ThreadLocal.ThreadLocalMap threadLocals = null;
threadLocals 是ThreadLocalMap类型的,ThreadLocalMap 是ThreadLocal的一个内部类。
源码中这个变量的注释如下:
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
大意:与线程相关的ThreadLocal变量,这个map由ThreadLocal类来操作。
所以在thread类中没有找到改变threadLocals值的地方。只有在exit()方法中对threadLocals置空。
2.ThreadLocal.ThreadLocalMap
1.ThreadLocalMap中还有一个内部类
static class Entry extends WeakReference<ThreadLocal>
有一个带参的构造函数叫Entry(ThreadLocal k, Object v),
从参数名字来看,Entry应该是一个弱引用的键值对,key是ThreadLocal的对象
2.ThreadLocal.ThreadLocalMap中有一个entry的数组,作为存储变量的容器
private Entry[] table;
3.ThreadLocal
1.set方法
public void set(T value) {
//获取当前线程
Thread t = Thread.currentThread();
//获取当前线程对应的map,return t.threadLocals; getMap直接返回当前线程的threadLocals,之前提过的那个
ThreadLocalMap map = getMap(t);
if (map != null)
//map非空将当前的threadlocal对象作为键,放到map中
map.set(this, value);
else
//map是空的话调用createMap函数创建map
createMap(t, value);
}
2.getMap函数
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
3.createMap函数
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
//firstKey就是this,当前的这个threadlocal对象,
ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY]; //创建entry数组
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);//将kv放入数组中
size = 1; //初始化数组
setThreshold(INITIAL_CAPACITY);//初始化数组容量
}
4.get函数
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();
}
总的来说ThreadLocal变量是这样的,Thread类中有一个ThreadLocalMap类型的map,这个map的entry是以ThreadLocal为key的,
value是范型可以随意指定。当一个线程定义了很多个ThreadLocal变量他们会存在这个map中,
所以把一个变量加入到threadlocal中就相当于该变量是线程私有属性,而且在这个线程的任何地方随存随取,所以threadlocal变量
是线程内全局,所有线程之间局部的。
另外:我们可以看下Entry的构造函数:
Entry(ThreadLocal k, Object v) {
super(k);
value = v;
}
entry的值只不过是v的引用的copy,就是entry的value实际指向的内存跟传进来的v指向的内存是同一个,所以对ThreadLocal的entryvalue操作
会改变原有的对象,所以加入到ThreadLocal变量并不等于新建了一个该变量的copy。ThreadLocal并不能解决共享变量的问题,所以也不能像很多
blog中说的解决多线程问题之类的。
ThreadLocal源码分析
标签:
原文地址:http://www.cnblogs.com/kniught-ice/p/5461101.html