private static final int VARIABLES_TO_REMOVE_INDEX = InternalThreadLocalMap.nextVariableIndex(); //InternalThreadLocal类型的缓存集合在InternalThreadLocalMap对应的下标
private final int index; //普通的缓存对象在InternalThreadLocalMap对应的下标(final修饰的变量为常量,表明一旦赋值后,就不能再改动,所以可以看出是一个对象一个index值(所以同一个InternalThreadLocal对象多次设值时,是会出现覆盖的)
public InternalThreadLocal() { //构建对象时,由InternalThreadLocalMap分配下标
index = InternalThreadLocalMap.nextVariableIndex(); //设置下一个游标值,每使用一个InternalThreadLocal,游标就会+1
}
public static void removeAll() { //移除所有绑定在当前线程的缓存值(包含普通对象和InternalThreadLocal对象)
InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.getIfSet();
if (threadLocalMap == null) {
return;
}
try {
Object v = threadLocalMap.indexedVariable(VARIABLES_TO_REMOVE_INDEX); //拿到InternalThreadLocal类型的缓存集合对应的下标
if (v != null && v != InternalThreadLocalMap.UNSET) {
Set<InternalThreadLocal<?>> variablesToRemove = (Set<InternalThreadLocal<?>>) v;
InternalThreadLocal<?>[] variablesToRemoveArray =
variablesToRemove.toArray(new InternalThreadLocal[variablesToRemove.size()]); //将集合Set转换为Map
for (InternalThreadLocal<?> tlv : variablesToRemoveArray) { //将每个InternalThreadLocal做移除操作
tlv.remove(threadLocalMap);
}
}
} finally {
InternalThreadLocalMap.remove();
}
}
private static void addToVariablesToRemove(InternalThreadLocalMap threadLocalMap, InternalThreadLocal<?> variable) {//添加InternalThreadLocal变量到缓存集合中(即处理第一个元素)
Object v = threadLocalMap.indexedVariable(VARIABLES_TO_REMOVE_INDEX);
Set<InternalThreadLocal<?>> variablesToRemove; //表示包含了多少个InternalThreadLocal实例
if (v == InternalThreadLocalMap.UNSET || v == null) {
variablesToRemove = Collections.newSetFromMap(new IdentityHashMap<InternalThreadLocal<?>, Boolean>()); //将Map值转换为Set
threadLocalMap.setIndexedVariable(VARIABLES_TO_REMOVE_INDEX, variablesToRemove);
} else {
variablesToRemove = (Set<InternalThreadLocal<?>>) v; //进行类型强转
}
variablesToRemove.add(variable); //InternalThreadLocalMap中的第一个元素是集合类型,如indexedVariables[0]为Collections$SetFromMap@1751
}
public final V get() { //从当前线程中获取当前维护的值(若没有查找到值,会进行初始化)
InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get(); //与set()获取InternalThreadLocalMap方式一致
Object v = threadLocalMap.indexedVariable(index); //获取当前对象对应index对应的值
if (v != InternalThreadLocalMap.UNSET) { //若值不为UNSET,则直接返回
return (V) v;
}
return initialize(threadLocalMap); //若不存在值,则进行初始化操作
}
private V initialize(InternalThreadLocalMap threadLocalMap) { //做初始化,并返回初始化后的值
V v = null;
try {
v = initialValue(); //调用子类重写的方法,若子类没有重写,则值为null
} catch (Exception e) {
throw new RuntimeException(e);
}
threadLocalMap.setIndexedVariable(index, v); //此处设置的逻辑,和set()的内部逻辑一致
addToVariablesToRemove(threadLocalMap, this);
return v;
}
public final void set(V value) {
if (value == null || value == InternalThreadLocalMap.UNSET) {
remove(); //设置的值为空时,做移除处理(与调用remove()方法是等价的)
} else {
InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get();
if (threadLocalMap.setIndexedVariable(index, value)) { //将值设置到InternalThreadLocalMap维护的数组中
addToVariablesToRemove(threadLocalMap, this); //将当前的InternalThreadLocal对象设置到缓存的InternalThreadLocal集合中
}
}
}
public final void remove(InternalThreadLocalMap threadLocalMap) { //从InternalThreadLocalMap中移除指定下标index对应的值(此处语义上不太好理解,就是没有通过方法参数传递index,而是通过操作成员变量的方式)
if (threadLocalMap == null) {
return;
}
Object v = threadLocalMap.removeIndexedVariable(index); // 1)移除指定下标的普通对象的缓存值,并返回移除前的值
removeFromVariablesToRemove(threadLocalMap, this); // 2)将当前InternalThreadLocal对象从InternalThreadLocal类型的缓存集合中移除
if (v != InternalThreadLocalMap.UNSET) { //当前InternalThreadLocal有设置过值,则对应回调子类方法
try {
onRemoval((V) v); // 3)看子类的具体移除实现(回调子类的方法)
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
private Object[] indexedVariables; //缓存对象对应的数组(不是static变量,非共享,每个对象各自维护,是线程安全的)
private static ThreadLocal<InternalThreadLocalMap> slowThreadLocalMap = new ThreadLocal<InternalThreadLocalMap>(); //原生的ThreadLocal,每个线程维护各自的线程变量(原生的ThreadLocal使用get()获取值时,会通过计算hashCode进行查找处理)
private static final AtomicInteger NEXT_INDEX = new AtomicInteger(); //记录数组可设值的下标(下一个设置的值,对应的下标,static变量,属于公共资源,初始值为0)
public static final Object UNSET = new Object(); //当未设置值时,给出的默认值(用于填充使用)
public static InternalThreadLocalMap get() { //获取InternalThreadLocalMap,返回的值若为空,会初始化对象返回
Thread thread = Thread.currentThread();
if (thread instanceof InternalThread) {
return fastGet((InternalThread) thread); //比较快的获取值
}
return slowGet(); //比较慢的获取值
}
public boolean setIndexedVariable(int index, Object value) { //设置线程局部变量的值(设置成功返回true)
Object[] lookup = indexedVariables; //引用赋值,lookup数组改变,indexedVariables数组也对应改变
if (index < lookup.length) {
Object oldValue = lookup[index];
lookup[index] = value;
return oldValue == UNSET; //@csy 此处是何意?解:若老的值为UNSET,说明值已经从UNSET -> value改变了
} else {
expandIndexedVariableTableAndSet(index, value); //扩容处理
return true;
}
}
private static InternalThreadLocalMap fastGet(InternalThread thread) { //比较快的获取InternalThreadLocalMap
InternalThreadLocalMap threadLocalMap = thread.threadLocalMap(); //从InternalThread直接获取
if (threadLocalMap == null) {
thread.setThreadLocalMap(threadLocalMap = new InternalThreadLocalMap());
}
return threadLocalMap;
}
private static InternalThreadLocalMap slowGet() { //比较慢的获取InternalThreadLocalMap
ThreadLocal<InternalThreadLocalMap> slowThreadLocalMap = InternalThreadLocalMap.slowThreadLocalMap;
InternalThreadLocalMap ret = slowThreadLocalMap.get(); //使用ThreadLocal获取,内部是通过hashCode去获取值的
if (ret == null) {
ret = new InternalThreadLocalMap(); //初始化InternalThreadLocalMap
slowThreadLocalMap.set(ret); //将值设置set到ThreadLocal中(get时可取到set的值)
}
return ret;
}
private void expandIndexedVariableTableAndSet(int index, Object value) { //扩容并设置线程变量的值
Object[] oldArray = indexedVariables;
final int oldCapacity = oldArray.length;
int newCapacity = index;
newCapacity |= newCapacity >>> 1; //无符号右移
newCapacity |= newCapacity >>> 2;
newCapacity |= newCapacity >>> 4;
newCapacity |= newCapacity >>> 8;
newCapacity |= newCapacity >>> 16;
newCapacity++;
Object[] newArray = Arrays.copyOf(oldArray, newCapacity); //使用数组拷贝
Arrays.fill(newArray, oldCapacity, newArray.length, UNSET);
newArray[index] = value;
indexedVariables = newArray;
}
InternalThread.get值时,是怎么区分当前线程的?一个线程能存储多个变量吗?
InternalThreadLocalMap#getIfSet待了解?
InternalThreadLocalMap功能用途是怎样的?怎么使用的?
InternalThreadLocalMap#fastGet与slowGet有什么差异?
InternalThreadLocal#VARIABLES_TO_REMOVE_INDEX变量的用途是什么?(OK)
InternalThreadLocal与InternalThread、InternalThreadLocalMap三者之间是怎么关联的?(OK)