做安卓的同学想必,一提到ThreadLocal会首先想到安卓中大名鼎鼎的handler消息机制,或许也大概是从了解handler消息机制开始接触并了解的ThreadLocal。
#ThreadLocal的特点及原理#
ThreadLocal的作用是保存线程内的共享变量,不同线程间不能互相访问。
ThreadLocal<String> tl = new ThreadLocal<>();
tl.set("天王盖地虎");
构造方法:
/**
* Creates a thread local variable.
* @see #withInitial(java.util.function.Supplier)
*/
public ThreadLocal() {
}
tl.set("xxx");方法
/**
* 给当前线程的threadlocal变量的拷贝设置指定的value值,大多数子类
* 不需要覆写这个方法,通过initialValue方法设置就可以了
*
* @param value 给当前线程的这个thread local的拷贝设置的值
*/
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变量
Thread.java#188
/* 属于这个Thread的ThreadLocalMap变量,由ThreadLocal类维护 */
ThreadLocal.ThreadLocalMap threadLocals = null;
set方法中的getMap返回当前线程的ThreadLocalMap变量
/**
* The entries in this hash map extend WeakReference, using
* its main ref field as the key (which is always a
* ThreadLocal object). Note that null keys (i.e. entry.get()
* == null) mean that the key is no longer referenced, so the
* entry can be expunged from table. Such entries are referred to
* as "stale entries" in the code that follows.
*/
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
Entry继承自WeakReference,扩展出一个Object变量,成为了键值对(ThreadLocal<?>, Object)的弱引用,很巧妙!
ThreadLocalMap是定义在ThreadLocal中的一个静态类,用来维护一个map结构,保存ThreadLocal和value的映射关系,这个映射关系就是Entry。
INITIAL_CAPACITY = 16;// 初始容量
private Entry[] table; // 一个Entry的table,可以扩容,值需要为2的幂
private int size = 0; // 这个table的大小
private int threshold; // 容量的阈值,用来判断是否需要扩容