Java 单线程代码ThreadLocal串值问题

Posted

Catch Spark. Code

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 单线程代码ThreadLocal串值问题相关的知识,希望对你有一定的参考价值。

ThreadLocal

ThreadLocal 适用于变量在线程间隔离,而在方法或类间共享的场景。

代码

 1 @RestController
 2 public class ThreadLocalController {
 3     private static final ThreadLocal<String> currentUid = ThreadLocal.withInitial(() -> null);
 4     @GetMapping("bad")
 5     public Map doBad(@RequestParam("uid") String uid) {
 6         String before = currentUid.get();
 7         currentUid.set(uid);
 8         String after = currentUid.get();
 9         Map result = new HashMap();
10         result.put("before", before);
11         result.put("after", after);
12         return result;
13     }
14 }

在application中做一下tomcat的配置

server.tomcat.max-threads=1

运行结果

第一次

 

 

第二次

 

按理说before总是null才对,为什么第二次运行却读取到了第一次的值呢?

只是因为我们的tocat会开启一个线程来调用我们的程序,而tomcat本身是有线程池的,会出现线程复用的情况。所以导致了问题。

修复

 1 @RestController
 2 public class ThreadLocalController {
 3     private static final ThreadLocal<String> currentUid = ThreadLocal.withInitial(() -> null);
 4     @GetMapping("good")
 5     public Map doGood(@RequestParam("uid") String uid) {
 6 
 7         try {
 8             String before = currentUid.get();
 9             currentUid.set(uid);
10             String after = currentUid.get();
11             Map result = new HashMap();
12             result.put("before", before);
13             result.put("after", after);
14             return result;
15         } finally {
16             currentUid.remove();
17         }
18     }
19 }

Key

tomcat线程池。

以上是关于Java 单线程代码ThreadLocal串值问题的主要内容,如果未能解决你的问题,请参考以下文章

Java并发编程:线程封闭--ThreadLocal

ThreadLocal的使用场景及实现原理

14Java并发性和多线程-Java ThreadLocal

java中的ThreadLocal详解及示例代码

既然spring中注入用单例,为了解决多线程安全问题,还得用theardlocal为每个线程创建共

ThreadLocal解析