具体实现

ThreadLocalMap

使用数组构建的一个map

伪代码结构

  1. Thread{
  2. ThreadLocalMap{
  3. TreadLocal(xx):1L
  4. TreadLocal(YY):2L
  5. }
  6. }

get的顺序
requestId.get() -> Thread.ThreadLocalMap -> ThreadLocal(requestId) -> 1L

ThreadLocal在Tomcat下线程重用中存在的问题

  1. public class WhController {
  2. private static final ThreadLocal<Integer> currentUser = ThreadLocal.withInitial(() -> null);
  3. @GetMapping("wrong")
  4. public Map wrong(@RequestParam("userId") Integer userId) {
  5. //设置用户信息之前先查询一次ThreadLocal中的用户信息
  6. String before = Thread.currentThread().getName() + ":" + currentUser.get();
  7. //设置用户信息到ThreadLocal
  8. currentUser.set(userId);
  9. try{
  10. //设置用户信息之后再查询一次ThreadLocal中的用户信息
  11. String after = Thread.currentThread().getName() + ":" + currentUser.get();
  12. //汇总输出两次查询结果
  13. Map result = new HashMap();
  14. result.put("before", before);
  15. result.put("after", after);
  16. return result;
  17. }finally {
  18. currentUser.remove();
  19. }
  20. }
  21. }

因为Tomcat是线程池来处理请求的, 所以有可能第二次的线程和第一次的线程是同一个线程,
尤其是设置了server.tomcat.threads.max=1 ,所以解决方案就是加finally 每次用完都remove,但是总觉得这样有问题
ThreadLocal 到底在实际中是如何使用的呢?


应用

spring事务