概念
Thread
ThreadLocal
ThreadLocalMap
Entry
关系
1,ThreadLocal 与 ThreadLocalMap
1,ThreadLocalMap 是一个静态内部类,是ThreadLocal这个类中的静态内部类
2,ThreadLocal中set方法
ThreadLocalMap中key是this,即ThreadLocal,value即是线程中需要存储的值
2,Thread 与 ThreadLocalMap
ThreadLocalMap 是Thread中一个变量
3,Thread 与 ThreadLocal
从ThreadLocal中获取变量时,先取的是这个线程Thread中的ThreadLocalMap,
ThreadLocalMap中存储的key是ThreadLocal。即二者还是通过ThreadLocalMap作为中间人,产生关联。
ThreadLocalMap是Thread的变量
ThreadLocalMap的key是ThreadLocal
4,Entry
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
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);
}
// new Entry. Entry是ThreadLocalMap中的一个静态内部类,这个类的变量value就是线程变量,
// 构造函数,中包含两个变量,一个是ThreadLocal 一个是value
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
// Entry存哪里 -> 数组中
table[i] = new Entry(firstKey, firstValue);
private Entry[] table; // 这个数组是ThreadLocalMap 中成员变量
总结
ThreadLocal是总领,它提供了一系列的方法,来实现线程间数据隔离
场景
1.全局数据传输 springsecurity 存储用户信息
2.线程间数据隔离 rocketmq 获取队列索引
ThreadLocalIndex
3,日志记录
当方法执行异常时,通过自定义注解获取入参,并写入异常日志表
但是当入参是T范型时,无法直接从入参中解析到具体某个入参,需要JSON进一步解析才能得到,那么这个入参怎么传递。
@Override
@OrderExceptionAnnotation(requestSnapshot = "#receiveOrder.orderInfo",sourceApp = Constant.WX)
public OrderResponse<ESBOrderResponse> commonCreateOrder(ReceiveOrder receiveOrder) {
ESBOrderInfoReq orderInfo = JSON.parseObject(JSON.toJSONString(receiveOrder.getOrderInfo()), new TypeReference<ESBOrderInfoReq>() {
});
ESBRoute route = orderInfo.getRoute();
ESBOrderDTO esbOrder = orderInfo.getEsbOrder();
//异常单业务逻辑,异常感知,全局变量输入
OrderThreadLocalContext.setOutOrderNo(esbOrder.getOutOrderNo());
return response;
}
// 入参
public class ReceiveOrder<T> extends OrderType implements Serializable {
private static final long serialVersionUID = -1L;
private T orderInfo;