ThreadLocal初解
简介
ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
类ThreadLocal的主要作用是将数据放入当前线程对象中的Map(ThreadLocal.ThreadLocalMap)中,这个Map是Thread的实例变量。
类ThreadLocal自己不管理、不存储任何数据,他只是数据和Map之间的桥梁,用于将数据放入Map中。
public class ThreadLocalTest {
private static ThreadLocal threadLocal = new ThreadLocal();
public static void main(String[] args) throws InterruptedException {
threadLocal.set("在main线程里放了一个值");
Thread a = new Thread(new Runnable() {
@Override
public void run() {
threadLocal.set("在a线程里放了一个值");
System.out.println(threadLocal.get());
}
}, "a");
a.start();
a.join();
System.out.println(threadLocal.get());
}
}
threadLocals与inheritableThreadLocals的区别是inheritableThreadLocals是可以继承的Map,子线程可以继承父线程的Map值
在Thread对象中threadLocals对应的Map key为一个ThreadLocal对象,多个线程可以将同一个ThreadLocal对象作为key.
ThreadLocalMap解析
ThreadLocalMap是ThreadLocal类中的一个静态内部类是默认的包可见,使用一个Entry做个Map的键值,K为ThreadLocal,V是一个Object
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
//构造函数
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
//初始一个大小为16的桶
table = new Entry[INITIAL_CAPACITY];
//通过key的threadLocalHashCode计算出桶中的位置
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
//初始化一个Entry
table[i] = new Entry(firstKey, firstValue);
//数量设置为1
size = 1;
setThreshold(INITIAL_CAPACITY);
}
//用于继承ThreadLocal的创建 在线程初始化过程中如果此线程是需要继承父线程的ThreadLocal值,则会间接调用此方法
private ThreadLocalMap(ThreadLocalMap parentMap) {
Entry[] parentTable = parentMap.table;
int len = parentTable.length;
setThreshold(len);
table = new Entry[len];
for (int j = 0; j < len; j++) {
Entry e = parentTable[j];
if (e != null) {
@SuppressWarnings("unchecked")
ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
if (key != null) {
Object value = key.childValue(e.value);
Entry c = new Entry(key, value);
int h = key.threadLocalHashCode & (len - 1);
while (table[h] != null)
h = nextIndex(h, len);
table[h] = c;
size++;
}
}
}
}
//可以重写此方法对父线程的value进项操作
T childValue(T parentValue) {
throw new UnsupportedOperationException();
}
threadLocal.get()源码解析
public T get() {
//获取当前线程
Thread t = Thread.currentThread();
//获取线程里的Map
ThreadLocalMap map = getMap(t);
//如果Map不为空
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
//根据threadLocal获取的值不为空
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
//设置初始值
return setInitialValue();
}
//根据线程获取Map
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
//InheritableThreadLocal是一个可继承的ThreadLocal重写了getMap方法
ThreadLocalMap getMap(Thread t) {
return t.inheritableThreadLocals;
}
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;
}
//可以重写该方法 设置初始值
protected T initialValue() {
return null;
}
//创建一个Map
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
threadLocal.set()源码解析
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}