具体实现
ThreadLocalMap
伪代码结构
Thread{
ThreadLocalMap{
TreadLocal(xx):1L
TreadLocal(YY):2L
}
}
get的顺序
requestId.get() -> Thread.ThreadLocalMap -> ThreadLocal(requestId) -> 1L
ThreadLocal在Tomcat下线程重用中存在的问题
public class WhController {
private static final ThreadLocal<Integer> currentUser = ThreadLocal.withInitial(() -> null);
@GetMapping("wrong")
public Map wrong(@RequestParam("userId") Integer userId) {
//设置用户信息之前先查询一次ThreadLocal中的用户信息
String before = Thread.currentThread().getName() + ":" + currentUser.get();
//设置用户信息到ThreadLocal
currentUser.set(userId);
try{
//设置用户信息之后再查询一次ThreadLocal中的用户信息
String after = Thread.currentThread().getName() + ":" + currentUser.get();
//汇总输出两次查询结果
Map result = new HashMap();
result.put("before", before);
result.put("after", after);
return result;
}finally {
currentUser.remove();
}
}
}
因为Tomcat是线程池来处理请求的, 所以有可能第二次的线程和第一次的线程是同一个线程,
尤其是设置了server.tomcat.threads.max=1 ,所以解决方案就是加finally 每次用完都remove,但是总觉得这样有问题
ThreadLocal 到底在实际中是如何使用的呢?
应用
spring事务