ThreadLocal与ThreadLocalMap
2020-04-09 本文已影响0人
lisx_
ThreadLocal是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不同的变量值完成操作的场景。
ThreadLocal的应用主要体现在looper的使用当中,它可以为每个不同的线程保存不同的值。下面主要探讨一下looper里ThreadLocal的使用情况。
从实例的创建开始, 大概流程是:
looper --》ThreadLocal --》ThreadLocalMap
ThreadLocal是Lopper里的一个常量。
@Lopper
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
ThreadLocalMap 是线程里的一个普通变量。
@Thread
ThreadLocal.ThreadLocalMap threadLocals = null;
Looper创建的时候会为ThreadLocal赋值,将Lopper自身保存到到当前线程的ThreadLocalMap中。ThreadLocal为key,looper为value。
@Looper
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
@ThreadLocal
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
//当ThreadLocalMap不存在时,可以为当前线程的ThreadLocalMap赋值
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
线程中的ThreadLocalMap可以保存多个ThreadLocal和存值。
threadLocal.jpgThreadLocalMap的定义在ThreadLocal中,是ThreadLocal的一个静态内部类,有map的概念。其中的key为ThreadLocal的弱引用(WeakReference)。
static class ThreadLocalMap {
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) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
}