ThreadLocal使用误区

17 篇文章 0 订阅
12 篇文章 0 订阅
[size=medium][color=red]场景:[/color][/size]
[color=darkred]应用服务器Tomcat[/color]

在LoginContext 中声明
private final static ThreadLocal<LoginContext> holder = new ThreadLocal<LoginContext>();

LoginContext 保存当前用户的基础信息,并保存到Redis缓存中

拦截器中有下面的操作

LoginContext loginContext = cache.get("key");
LoginContext.setLoginContext(loginContext);

这样,每次似乎当前线程都是最新的LoginContext;

[size=medium][color=red]问题:[/color][/size]
用户不定时自动登出


[size=medium][color=red]分析及解决:[/color][/size]

补充相关日志及分离日志文件,看到有和登出有关的日志里面,
很多时候,可以看到用户调用了登出(logout)接口(不是用户本人做了登出),然后就有用户登出了

查看Redis源码和拦截器相关操作,Redis的API在使用上应该没有问题,突然想到是不是loginContext在线程池中被串用了?

尝试在拦截器后处理(postHandle)中清理该LoginContext

问题之后没有出现

后续进一步分析过程中,发现logout接口没有被进过拦截器(在spring配置文件中被排除了)
问题的根源就在这:
别人登出,可能用到另一个人使用的线程(Tomcat使用的是线程池),该线程里面保存了这个LoginContext,结果把别人给登出了

注:必须在postHandle加remove,防止配置错误时出现线程池情况下,相关信息串用,导致系统不稳定
ThreadLocal是一个Java类,用于在多线程环境下保存线程本地变量的副本。通过创建ThreadLocal对象,每个线程都可以拥有自己独立的变量副本,互不干扰。 使用ThreadLocal的过程如下: 1. 创建一个ThreadLocal对象,可以指定泛型类型。 2. 在每个线程中,通过ThreadLocal对象的`get()`方法获取当前线程的变量副本。如果当前线程没有设置过变量值,则会使用默认值进行初始化。 3. 在每个线程中,通过ThreadLocal对象的`set(value)`方法设置当前线程的变量值。 4. 在每个线程中,通过ThreadLocal对象的`remove()`方法移除当前线程的变量副本。 需要注意的是,ThreadLocal对象的生命周期与Thread对象的生命周期一样长。当ThreadLocal对象被垃圾回收时,关联的变量副本也会被回收。 在ThreadLocal内部,使用ThreadLocalMap来存储每个线程的变量副本。ThreadLocal的实例作为key,变量值作为value。ThreadLocalMap可以使用强引用或弱引用来引用ThreadLocal对象。如果使用强引用,当ThreadLocal对象被回收时,如果没有手动删除对应的变量副本,会导致内存泄漏。如果使用弱引用,当ThreadLocal对象被回收时,对应的变量副本也会被回收。 总结来说,ThreadLocal是一种线程本地变量,通过保存每个线程的变量副本,实现了多线程环境下的线程隔离。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ThreadLocal使用与原理](https://blog.csdn.net/qq_35190492/article/details/116431270)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ThreadLocal使用详解](https://blog.csdn.net/LJJZJ/article/details/88763666)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值