ThreadLocal

ThreadLocal实际上相当于一个工具类,我们使用ThreadLocal类就是和它打交道,本身并不存储什么,真正起作用的是内部类ThreadLocalMap。
ThreadLocal类作为Key存储在ThreadLocalMap中,通过ThreadLocal可以拿到存储的value值。

ThreadLocalMap

ThreadLocal的静态内部类,每个Thread内部都有ThreadLocalMap的成员变量,我们在调用ThreadLocal.set()方法时,实际上会拿到当前线程的ThreadLocalMap成员变量,如果为空则去创建,不为空则进行变量保存。

ThreadLocalMap才是真正用来存储的工具,内部维持一个使用线性探测法实现的哈希表(不是拉链法),初始数组长度为16,当数据达到2/3时进行扩容,每次增加一倍。

ThreadLocal的hash值在生成的过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private final int threadLocalHashCode = nextHashCode();
/**
* The next hash code to be given out. Updated atomically. Starts at
* zero.
*/
private static AtomicInteger nextHashCode = new AtomicInteger();
/**
* The difference between successively generated hash codes - turns
* implicit sequential thread-local IDs into near-optimally spread
* multiplicative hash values for power-of-two-sized tables.
*/
private static final int HASH_INCREMENT = 0x61c88647;
/**
* Returns the next hash code.
*/
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}

上述算法中使用0x61c88647可以让hash的结果在2的n次方内尽可能均匀分布,减少冲突的概率。

ThreadLocalMap的作用域是单个线程内,所以不存在线程间共享数据的问题,也不用考虑线程同步。

不要拿synchronized和ThreadLocal比,两者没有可比性,因为原理和用途完全不一致。

Entry

存储的实体类,继承于WeakReference,对ThreadLocal进行弱引用,同时存储value。Entry实例被存在哈希表中。

文章目录
  1. 1. ThreadLocalMap
  2. 2. Entry
|