ThreadLocal的理解和使用

理解

ThreadLocal是一种用于在多线程环境中存储线程局部变量的机制,它为每个线程都提供了独立的变量副本,从而避免了线程之间的竞争条件,事实上ThreadLocal的工作原理是在每个线程中创建一个独立的变量副本,并且每个线程只能访问自己的副本。ThreadLocal一个最广泛的使用场景就是将信息保存,从而方便后续方法直接从线程中获取。

ThreadLocal核心方法
方法声明描述
public void set(T value)设置当前线程绑定的局部变量
public T get()获取当前线程绑定的局部变量
Public void remove()移除当前线程绑定的局部变量
TheadLocal使用
public class LoginUserContextHolder {
    
    /**
     * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
     * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
     */
    private static final ThreadLocal<LoginUser> threadLocal = new ThreadLocal<>();

    /**
     * 设置变量
     */
    public static void set(LoginUser user) {
        threadLocal.set(user);
    }

    /**
     * 获得变量
     */
    public static LoginUser get() {
        return threadLocal.get();
    }

    /**
     * 清理当前变量
     */
    public static void remove() {
        threadLocal.remove();
    }
}

实际例子: 前端使用token令牌调用后端接口,后端在Filter(过滤器)中拦截token令牌,然后判断token是否有效可用,从而可获取登录时存储在Redis中的用户信息,然后通过上述方法将登录用户信息放入到ThreadLocal中,那么在执行到接口层就可通过ThreadLocal获取到当前登录用户信息。

注意点

使用完后要进行手动释放,要不然会造成内存泄漏,也可能导致意外的数据污染或不一致性。

内存泄漏:上述threadLocal对象,若没有手动删除当前线程的用户信息,每次请求执行接口时都会创建一个不同的线程,都会将用户信息放到threadLocal对象中,而threadLocal的生命周期相当于应用系统的生命周期,GC无法回收,这样就会导致执行接口次数越多,内存泄漏得越多。

数据污染或不一致性:上述threadLocal对象,若没有手动删除当前线程的用户信息,可能会导致不同的token令牌请求(用户不同)会得到同一个用户信息。主要原因是使用线程池,线程池是拥有核心线程数和最大线程数的,核心线程会一直存在那里不会销毁,核心线程外的最大线程是有一定的存活时间,那么就有可能当前接口的线程就存活在线程池中,从而得到错误的用户信息。

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如风之夏

感谢,你的鼓励是我前进的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值