基础知识: ThreadLocal 内部是用一个map结构,key为thread,value可以为业务对象,可以将多个线程隔离开来
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
private static final int INITIAL_CAPACITY = 16;
private Entry[] table;
private int size = 0;
private int threshold;
private void setThreshold(int len) {
threshold = len * 2 / 3;
}
private static int nextIndex(int i, int len) {
return ((i + 1 < len) ? i + 1 : 0);
}
private static int prevIndex(int i, int len) {
return ((i - 1 >= 0) ? i - 1 : len - 1);
}
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
ThreadLocal在实现上,是让每个线程在自己的内部单独持有一个变量,线程之间就不会有竞争出现,所以不需要采用并发对象ConcurrentHashMap。
不使用HashMap原因 ThreadLocalMap不存在多个key具有相同hashcode的问题,因而数据存储不需要像hashmap那样设计成数组+链表的形式,只需要数组就可以。 一个线程生成后,很久没有再次调用,我们为了保证系统的可用性,需要对线程资源进行回收,因而ThreadLocalMap的entry是需要继承 WeakReference的,便于即使回收
|