ThreadLocal其实原理是创建了多份相同数据保存在堆内存上,每个线程的Thread类里有ThreadLocal.ThreadLocalMap threadLocals的属性来指向存位置,
所以每个线程修改都不会影响到其他线程的数据
首先说下下面用到的东西:ThreadLocalMap为ThreadLocal的静态内部类,他有Entry[]数组来存放本地变量
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
ThreadLocal get方法源码 它会调用getMap(t)方法,这个getMap()方法会返回当前线程的ThreadLocalMap的实例,通过ThreadLocalMap的getEntry()方法
根据当前ThreadLoad获取到Entry后取得值。如果当前线程没有ThreadLocalMap的引用,则初始化一分数据并将引用传给当前线程。
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();
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
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;
}
ThreadLocal set方法也是通过getMap方法获取到当前线程对应的ThreadLocalMap后设置值,如果map为空则先为线程创建ThreadLocalMap并将值放入以当前
ThreadLocal为Entry的K
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}