一个 Thread 对象 内部成员变量 locals 是一个 ThreadLocalMap 对象
一个 ThreadLocalMap 存放 Key 为 ThreadLocal 对象,值为副本
一个 Thread 一个 ThreadLocalMap
一个 ThreadLocalMap key 可以对应 多个 ThreadLocal 对象
一个 ThreadLocal 对象在同一个 ThreadLocalMap 里作为 key ,Value 用于存放值副本
1 个 Thread : 1 个 ThreadLocalMap
1 个 ThreadLocalMap : N 个 (KEY) ThreadLocal
1 个 ThreadLocal 在一个 ThreadLocalMap 内 : 1 个 Value
1 个 Thread 对应 1 个 ThreadLocalMap
1 个 ThreadLocalMap 对应 多对 不同 ThreadLocal:Value
1 个 ThreadLocal 在 1个ThreadLocalMap中,只能有一条键值对记录,所以一条ThreadLocal作为Key,在同一个ThreadLocalMap 中 只对应一个值, 且只有这一条键值对(因为键唯一)
为了适应不同的人、面试官、等的水平或理解方式的差异
写了很多废话,没办法,为了短时间内在不了解对方的情况下,猜中对方能听懂哪个版本,并且自己表达能力也比较有限吧,主要精力应该是自己理解懂原理,而不是翻译成各种句式给A,B,C,D 等人听懂(但是尽量)
ThreadLocal.get 方法
获取 当前Thread 的 ThreadLocalMap 中的 以当前ThreadLocal对象为key的 value。
ThreadLocalMap 中用
Entity[] tab 作为hash表
执行散列:
表的索引 i 是 取 ThreadLocal 对象的成员字段 threadLocalHashCode作为 hash值 然后再 对 tab长度取莫得到
ThreadLocal 对象的成员字段 threadLocalHashCode 为自增长字段 类型是 static AtomicInteger,也就是说 每 new 一个 ThreadLocal 字段就会将这个值 返回作为新的这个ThreadLocal的 threadLocalHashCode ,并自增 0x61c88647
碰撞处理:
当hash一致时,使用线性探测法,将下标+1 取出对应的 Entry 对象,判断其 key (ThreadLocal对象),是否为同一个,如果不是,说明碰撞,继续下标+1查找,直到null
android 中 ThreadLocalMap 的主要区别是
ThreadLocalMap 类被替换成 ThreadLocal.Value 包级静态内部类。
Entity[] tab 这个散列表 该为 Object[] table;
table 的长度为 Entity[] tab 的2倍,因为 偶数下标放key Object, 奇数下标放value Object。
所以计算key的 hash 的时候,ThreadLocal的自增hash为 0x61c88647 * 2, 这样保证hash 被table长度按位与运算后,下标的散列值是 偶数。
this.mask = table.length - 1;
int index=key.hash&mask