7、ThreadLocal底层实现
每个Thread都有一个ThreadLocalMap对象,ThreadLocalMap持有对象的引用,
该对象跟当前线程绑定,ThreadLocalMap以当前的threadLocal对象为key,
以ThreadLocal里面存的值为value。保存一份变量的副本,副本保存在线程中的,
而不是保存在ThreadLocal变量中;从而实现线程之间的数据的隔离
复制代码
8、 ThreadLocal源码:
1)、set()方法:
public void set(T value) {
//获取当前线程对象
Thread t = Thread.currentThread();
//获取当前线程对象的ThreadLocalMap
ThreadLocalMap map = getMap(t);
if (map != null)
//以当前threadLocal对象为key,实际存储对象为value
map.set(this, value);
else
createMap(t, value);
}
//获取Thread类中的ThreadLocalMap对象
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
//创建Thread类中的ThreadLocalMap成员对象
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
//初始化ThreadLocalMap对象
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
//INITIAL_CAPACITY初始值为16
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
//初始化加载因子
private void setThreshold(int len) {
threshold = len * 2 / 3;
}
2)、get()方法:
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
//threadlocal实例为key获取到对应Entry,然后从Entry中取出对象
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
//map为空时,设定初始值
return setInitialValue();
}
private T setInitialValue() {
T value = initialValue();
//同set方法一样
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
protected T initialValue() {
return null;
}
3)、remove()方法:
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
复制代码
9、ThreadLocal使用场景(JDBC的连接、管理会话HttpSession等)
如图: