ThreadLocal 随笔
写在前面
ThreadLocal 通常是将类的私有静态变量(全局唯一并且基本不会发生改变)与之绑定,方便上下文信息交互。比如 TransactionId 或 userId 等。
一个线程可以声明多个 ThreadLocal 对象,使用 ThreadLocalMap 进行维护。
ThreadLocalMap<ThreadLocal, V> 是一个自定义的 hashMap。 ThreadLocal 对象做 key,方便查询时快速定位到某个ThreadLocal节点。
工作原理
扩容机制
ThreadLocalMap 在内部节点的数量大于阈值(总数量 * 2/3)时,会尝试进行 rehash。首先清除当前无效的数据(索引下标对象不为空,并且调用 get 方法无法获取到对象),如果清除之后的数据仍大于总容量的 1/2,就会执行 resize 方法,容量为原来的二倍,同时重新计算对象在新坐标的位置(hashCode & len)。
内部同样采用二的整数幂作为计算单位,新 table 的位置也总是以 2 的整数幂作为单位偏移
如何实现与线程绑定?
Thread 内部有 threadLocals 和 inheritableThreadLocals 的 ThreadLocalMap 全局变量,在线程调用方调用 set 方法时,首先获取当前线程下的 threadLocals ,尝试插入到该 map 中,如果不存在,则创建新的
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
// getMap 私有方法
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
// createMap 私有方法
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue