ThreadLocal是一个关于创建线程局部变量的类。对于 ThreadLocal 的原理分析,我们从 Android 的Looper类开始分析,我们知道 Looper.myLooper() 会返回当前 Thread 的 Looper。我们就来看看 myLooper() 方法为什么可以返回当前线程的 Looper,而不是其他线程的 Looper。
Looper的主要相关代码如下:
public final class Looper {
//通过 ThreadLocal 保存当前线程的 Looper
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
...
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
//保存当前线程的 Looper
sThreadLocal.set(new Looper(quitAllowed));
}
//获取当前线程的 Looper
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
...
}
获取当前线程的 Looper 是通过 ThreadLocal 类的 get() 方法来获取的,我们来看下它的代码实现:
public class ThreadLocal<T> {
//获取当前线程存储的值
public T get() {
//1、获取到当前线程
Thread t = Thread.currentThread();
//2、获取当前线程 t 的 ThreadLocalMap 成员变量 map
ThreadLocalMap map = getMap(t);
if (map != null) {
//3、将this 作为 key 得到 entry
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
//4、拿到需要返回的值
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
//直接返回 thread 的成员变量 threadLocals
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
//第一次 map 为 null,需要调用 createMap 初始化 map。
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
}
ThreadLocalMap 是 ThreadLocal 的一个内部静态类,它是用来保存数据的,它的 getEntry() 方法如下:
static class ThreadLocalMap {
private Entry getEntry(ThreadLocal<?> key) {
int i = key.threadLocalHashCode & (table.length - 1);
Entry e = table[i];
if (e != null && e.get() == key)
return e;
else
return getEntryAfterMiss(key, i, e);
}
}
这里的关键是 Thread 类保存了一个成员变量 ThreadLocal.ThreadLocalMap,所以每个线程都有一个 map 来保存值。
public class Thread implements Runnable {
...
ThreadLocal.ThreadLocalMap threadLocals = null;
...
}
从上面的流程可以看出 ThreadLocal 类的 get 主要原理步骤就是:
- 获取到当前线程
- 获取到当前线程的 ThreadLocal.ThreadLocalMap 成员变量
- 从成员变量 map 中取值或存值