关于ThreadLocal在Tomcat中遇到的问题
Tomcat服务器默认是使用线程池管理线程.对于客户端的每次请求,Tomcat会为每次请求分配一个空闲的线程来处理请求,当其他请求tomcat时,不会将正在处理请求的线程来处理这次请求.
ThreadLocal叫做线程变量,意思是在ThreadLocal中储存的变量只属于当前线程.了解关于ThreadLocal更多在底部第二个链接.
- 遇到的问题:
例如:在单纯使用(指在没有用拦截器之前或其他之前) ThreadLocal储存当前登录用户id,两个不同的用户user_1,user_2,先登录了user_1,后登录了user_2,结果发现user_2可以查询到user_1的数据.
- 在观察后发现:
user_2在ThreadLocal中得到了user_1的id,为什么会得到user_1的id?
逻辑: tomcat为每次请求分配空闲线程,相当于就为两个用户分配了不同线程,然后在属于各自的ThreadLocal中储存了id.按理来说user_2就不可能得到user_1的id,这里能得到user_1的id就说明user_2得到了并且用的是user_1的ThreadLocal,那就说明user_1和user_2是有同一个线程处理的. ???为什么,原来是因为user_1先登录,tomcat为这次请求分配了一个空闲线程来处理,user_1登陆后,这次请求就结束了,这个线程就成为了空闲状态,而user_2后登录,tomcat再次分配空闲线程,就恰好分配了user_1使用的线程.所以就造成了这种情况.
- 解决:
在每次请求后,清理之前user存入的数据.对于每次请求后都需要清理,可以在使用拦截器的时候,在后置处理时清理,以简化代码重复
借鉴于:
https://blog.csdn.net/m0_53805458/article/details/127695485
https://blog.csdn.net/u010445301/article/details/111322569?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168615216216800222834479%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168615216216800222834479&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-111322569-null-null.142v88insert_down38v5,239v2insert_chatgpt&utm_term=ThreadLocal&spm=1018.2226.3001.4187