Thread、ThreadLocal、ThreadLocalMap 关系
Thread 和ThreadLocal 关系: ThreadLocal: 各自线程, 人手一个
ThreadLocal 和 ThreadLocalMap 关系 :
代码:
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
static class ThreadLocalMap {
/**
* The entries in this hash map extend WeakReference, using
* its main ref field as the key (which is always a
* ThreadLocal object). Note that null keys (i.e. entry.get()
* == null) mean that the key is no longer referenced, so the
* entry can be expunged from table. Such entries are referred to
* as "stale entries" in the code that follows.
*/
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
// createMap(t, value);
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY]; // 16
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
关系图
总结
threadLocal是一个壳子,真正的存储构是threadLocal里有ThreadLocalMap这么个内部类,每个thread对象都维护了一个threadLocalMap的引用。threadlocalmap是threadlocal的内部类,用entry来进行存储。
1》调用threadlocal的set()方法时,实际上就是往thradlocalmap设置的key是threadlocal对象,值value是传递进来的对像
2》调用threadlccal的get()方法时,实际上:就是往threadlocalmap获取值,key是threadlocal对象
threadlocal本身并不存储值(threadlocal是一个壳子),它只是自己作为一个key来让线程从ThreadlocalMap中获取value数值。
因为这个原理,所以threadloca能够实现"数据隔离",获取当前线程的局部变量值,不受其他线程影响~