没有意识到线程重用导致用户信息错乱的 Bug
spring 是运行在tomcat容器之中的, tomcat 的工作线程是基于一个全局的线程池, 那么就是说实际上spring的线程是重复使用的,如果在使用 threadLocal 之前没有先清除, 而是直接进行使用, 就会造成问题.
@RequestMapping("/demo")
@RestController
@Log4j2
@Api("demo api")
public class DemoController {
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);
//设置用户信息之后再查询一次ThreadLocal中的用户信息
String after = Thread.currentThread().getName() + ":" + currentUser.get();
//汇总输出两次查询结果
Map result = new HashMap();
result.put("before", before);
result.put("after", after);
log.info("result: {}", result);
return result;
}
}
多次请求接口后, 结果:
Writing [{before=http-nio-8080-exec-5:12, after=http-nio-8080-exec-5:12}]