当前位置: 首页 > article >正文

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令牌请求(用户不同)会得到同一个用户信息。主要原因是使用线程池,线程池是拥有核心线程数和最大线程数的,核心线程会一直存在那里不会销毁,核心线程外的最大线程是有一定的存活时间,那么就有可能当前接口的线程就存活在线程池中,从而得到错误的用户信息。


http://www.kler.cn/news/155124.html

相关文章:

  • IntelliJ IDEA 之初体验(上)
  • [LeetCode周赛复盘] 第 374 场周赛20231203
  • 图像生成MaaS服务
  • chatgpt prompt提示词
  • abapgit 安装及使用
  • Redis集合对象
  • 对某登录站点的JS前端逆向思路
  • Git中如何按日期进行checkout
  • React--引入第三方插件时,标签名是小写报错问题
  • 创意项目开源,文生图、排序/优选等...,持续开源更新!!
  • docker-速通
  • Django大回顾 -3 之响应对象、cbv和fbv、关于类中self是谁的问题、上传文件、模版
  • 引用计数 Rc 数据类型
  • 【Python百宝箱】分布式魔法:穿越分布式奇境的导航
  • 深度学习——第1章 深度学习的概念及神经网络的工作原理
  • LeetCode 1423. 可获得的最大点数:滑动窗口
  • 智加科技获全国首张重卡无人驾驶开放道路测试牌照
  • RabbitMQ架构是什么样的
  • 【SpringBoot】讲清楚日志文件lombok
  • Hdoop学习笔记(HDP)-Part.09 安装OpenLDAP
  • mongodb查询数据库集合的基础命令
  • 学习Java第57天,Servlet的基本使用步骤
  • PTA结构体经典编程题
  • Android studio Load error:undefined path variables
  • ARM架构安全简介
  • 数据链路层之VLAN基本概念和基本原理
  • springboot 整合 RocketMQ 可用于物联网,电商高并发场景下削峰,保证系统的高可用
  • HarmonyOS应用开发——程序框架UIAbility、启动模式与路由跳转
  • 鸿蒙绘制折线图基金走势图
  • 一缕青丝寄相思