首页 > 其他分享 >ThreadLocal 快速入门

ThreadLocal 快速入门

时间:2024-03-13 14:31:37浏览次数:26  
标签:入门 登录 局部变量 用户 ThreadLocal 线程 快速 id

ThreadLocal 快速入门

ThreadLocal 是 Java 中的一个类,用于创建线程局部变量。线程局部变量是一种特殊的变量,每个线程都有自己的副本,互相之间不会相互影响。这在多线程环境中非常有用,可以避免线程间共享变量导致的并发问题。

  1. 定义与作用ThreadLocal 是 Java 中的一个类,用于创建线程局部变量。它提供了一种在每个线程中都创建独立副本的机制。这意味着每个线程都可以访问自己的变量副本,而不会影响其他线程。
  2. 使用场景
    • 线程安全性:在多线程环境中,使用 ThreadLocal 可以避免共享变量的竞争条件,提高程序的线程安全性。
    • 上下文传递:有些情况下,需要在同一个线程的不同方法之间传递数据,但又不希望使用方法参数或全局变量。这时候可以使用 ThreadLocal 来存储线程相关的数据,方便在整个线程的执行过程中访问。例如:项目中想要获取登录人的id,就可以使用ThreadLocal
    • 线程封闭:有些对象是线程不安全的,但是如果每个线程都有自己的副本,就可以避免共享对象导致的线程安全问题。
  3. 使用方式
    • 创建 ThreadLocal 对象:可以直接实例化 ThreadLocal 类,也可以通过 ThreadLocal 的静态方法 withInitial(Supplier<? extends S> supplier) 来创建并初始化 ThreadLocal 实例。
    • 设置值:通过 set(T value) 方法设置当前线程的变量副本的值。
    • 获取值:通过 get() 方法获取当前线程的变量副本的值。
    • 移除值:通过 remove() 方法移除当前线程的变量副本。
  4. 内存泄漏问题: 使用 ThreadLocal 时需要注意内存泄漏的问题。因为 ThreadLocal 是与线程绑定的,如果线程不结束,ThreadLocal 中的值可能无法释放,导致内存泄漏。为了避免这个问题,最好在使用完 ThreadLocal 后调用 remove() 方法将其值移除。
  5. 线程池中的使用: 在使用线程池的情况下,需要特别小心 ThreadLocal 的使用。因为线程池中的线程是可以被复用的,如果 ThreadLocal 的值没有在使用完后及时清理,可能会影响到其他任务的执行。通常建议在使用完 ThreadLocal 后手动调用 remove() 方法清理。

ThreadLocal常用方法:

A. public void set(T value) : 设置当前线程的线程局部变量的值

B. public T get() : 返回当前线程所对应的线程局部变量的值

C. public void remove() : 删除当前线程所对应的线程局部变量的值

我们可以在LoginCheckFilter的doFilter方法中获取当前登录用户id,并调用ThreadLocal的set方法来设置当前线程的线程局部变量的值(用户id),然后在MyMetaObjectHandler的updateFill方法中调用ThreadLocal的get方法来获得当前线程所对应的线程局部变量的值(用户id)。 如果在后续的操作中, 我们需要在Controller / Service中要使用当前登录用户的ID, 可以直接从ThreadLocal直接获取。

案例:

项目中想要获取登录人的id

1).BaseContext工具类

/**
 * 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id
 */
public class BaseContext {
    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
    /**
     * 设置值
     * @param id
     */
    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }
    /**
     * 获取值
     * @return
     */
    public static Long getCurrentId(){
        return threadLocal.get();
    }
}

2).LoginCheckFilter中存放当前登录用户到ThreadLocal

在doFilter方法中, 判定用户是否登录, 如果用户登录, 在放行之前, 获取HttpSession中的登录用户信息, 调用BaseContext的setCurrentId方法将当前登录用户ID存入ThreadLocal。

Long empId = (Long) request.getSession().getAttribute("employee");
BaseContext.setCurrentId(empId);

image-20210801162053581

3). MyMetaObjectHandler中从ThreadLocal中获取

将之前在代码中固定的当前登录用户1, 修改为动态调用BaseContext中的getCurrentId方法获取当前登录用户ID

image-20210801162345846

image-20210801162436740

标签:入门,登录,局部变量,用户,ThreadLocal,线程,快速,id
From: https://blog.csdn.net/m0_74212228/article/details/136657312

相关文章

  • ThreadLocal底层原理
    ThreadLocal是Java中的一个线程局部变量工具类,它允许每个线程都有自己独立的变量副本,而不会相互干扰。ThreadLocal的底层原理涉及到ThreadLocalMap和Thread类。在ThreadLocal内部,使用一个ThreadLocalMap对象来存储每个线程对应的变量值。当调用set()方法设置......
  • 优秘智能开源AICMS:快速开发AIGC应用的必备,SAAS营销管理和AI的API全方位接入
    随着人工智能技术的飞速发展,AIGC(AIGeneratedContent)已经成为了当今科技领域的热门话题。为了帮助更多的企业和开发者快速开发AIGC应用,优秘智能近日开源了其强大的AICMS(AIContentManagementSystem)平台,助力开发者高效构建各类AIGC应用。一、优秘智能AICMS简介优秘智能是......
  • springmvc入门登录功能
    学习springmvc的时候的一个入门功能,登录功能。配置好web框架,导入需要springjar包和springmvc需要的两个jar包,就可以编码了,首先写了登录需要的jsp页面<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>Title</title></hea......
  • 毕业论文攻略:快速完成,轻松毕业!
    制定计划,合理分阶段......
  • 数据结构算法系列----快速幂
    一、快速幂的介绍:1、为什么要使用快速幂:   当我们计算a的n次幂时,最先想到的肯定是c中的内置函数  pow(a,n),这个内置函数虽然简单方便,但是在实际使用中这个函数的时间复杂度是o(n),因为它是将a乘n次得到的答案。  由于在n非常大时用pow()很容易超时,因此我们引入一个时......
  • C语言入门学习 --- 7.结构体
    文章目录第七章结构体1.结构体的声明1.1结构的基础知识1.2结构的声明1.3结构成员的类型1.4结构体变量的定义和初始化2.结构体成员的访问2.1结构体变量访问成员2.2结构体指针访问指向变量的成员3.结构体传参配套练习:第七章结构体1.结构体类型的声明2.结构体初始......
  • C语言入门学习 --- 9.编程练习题
    1.正整数A和正整数B的最小公倍数是指能被A和B整除的最小的正整数,设计一个算法,求输入A和B的最小公倍数。输入描述:输入两个正整数A和B。输出描述:输出A和B的最小公倍数。输入:57输出:35#include<stdio.h>intmain(){ inta=0; intb=0; inti=0; scanf("%d%......
  • 算法入门书籍(二)--2024.03.13
    小学C++编程入门书籍及相关资料介绍(二)算法篇小学C++编程入门书籍及相关资料介绍(二)算法篇_c++教材-CSDN博客 算法入门书籍--2022.04.04算法入门书籍--2022.04.04-CSDN博客1、聪明人的游戏信息学探秘.提高篇-2017年06月2、啊哈!算法3、哇,编程!——跟小明一起学......
  • 使用IDEA+groovy快速生成entity、dto、dao、service、serviceImpl
    groovy代码importcom.intellij.database.model.DasTableimportcom.intellij.database.util.Caseimportcom.intellij.database.util.DasUtilimportjava.text.SimpleDateFormat/**Availablecontextbindings:*SELECTIONIterable<DasObject>*PROJ......
  • JavaScript学习--splice()函数入门与精通
    一、splice入门splice方法:通过删除(两个参数)或替换现有元素(三个参数)或者原地添加新的元素(三个参数)来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。参数:index——必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置(从1开始)。howmany——必需......