ThreadLocal 解读
ThreadLocal
是 Java 中一个用来创建线程局部变量的类。它为每个使用该变量的线程提供独立的变量副本
线程局部变量意味着对于同一个 ThreadLocal
实例,在不同的线程中访问到的值是不同的,每个线程都有自己的变量副本。这样可以在多线程环境下保证变量的线程安全性。
————
先理解两个概念:
一个Java项目就占用操作系统一个进程,而Java自身又有两个线程概念:
1.系统线程:
是在 Java 程序运行时由 JVM(Java 虚拟机)底层创建和管理的线程。这些线程是 Java 自己的线程,与操作系统的线程(例如 Windows、Linux 等)不同。Java 线程是由 JVM 虚拟出来的,对于操作系统来说,它们只是一个进程的内部实现,无法直接感知。
系统线程通常用于执行 Java 应用程序的各种任务,例如垃圾回收、编译优化、监控和管理等。
2.用户线程:
在理论上,一个系统线程(即由 JVM 管理的线程)可以处理数百个用户线程。例如:当一个用户线程遇到了 IO 操作,它会发起相应的 IO 请求,然后被挂起等待 IO 操作完成。在等待期间,系统线程可以选择去处理其他的用户线程,也可以执行一些其他的任务,例如处理其他用户线程的计算任务、执行垃圾回收等。
**用户线程是由程序员在 Java 应用程序中显式创建和调度的线程。**在 Java 中,程序员可以通过创建 Thread
对象或者实现 Runnable
接口来创建自己的线程,并通过调用 start()
方法启动线程。
每个用户线程都有自己的线程 ID,这个 ID 是由 JVM 分配的,用于标识当前线程的唯一标识符。
一个用户线程处理一个用户的一次请求,下一次请求可能是其他线程去处理了。
Java 线程池中的线程数量设置就是用来管理被提交到线程池执行的用户线程数量的(后续讲线程池)
————————
理解清楚了上面的两个线程概念后,举个生活中的例子方便大家理解ThreadLocal:
- 可以将线程池、系统线程、用户线程等比喻为医院的工作人员,而 ThreadLocal 则是每个工作人员(护士)的大脑记忆。
一个程序就像一个医院,系统线程像是护士长,负责管理和分配任务给各个护士。每个用户线程就像是一个护士,她处理着用户的一次请求(病人的一次需求)。 而这时候ThreadLocal就是每个护士的大脑记忆,它需要记住对应的病人的一次需求内容是啥(用来记录和存储当前正在处理的用户请求的相关信息)。可是情况不是固定的,病人可能有着很多的需求,病人可能前一会是想要测血压;几秒后又想打葡萄糖了,这样子这两个需求是不同的,这个时候的ThreadLocal就起到作用了,它是属于每个护士独立的记忆,所以这样需求对象就不会被覆盖啥的。(这样可以确保不同的用户请求不会相互干扰,避免出现数据错乱或混乱的情况。)
——————
内部方法:
threadLocal.set(T value): 设置线程内初始化实例对象。
threadLocal.get(): 获取线程内该实例对象。
threadLocal.remove(): 移除线程内实例对象。
——————
通常业务使用案例:
/*** 身份验证信息*
*/
public class AuthenticationContextHolder
{private static final ThreadLocal<Authentication> contextHolder = new ThreadLocal<>();public static Authentication getContext(){return contextHolder.get();}public static void setContext(Authentication context){contextHolder.set(context);}public static void clearContext(){contextHolder.remove();}
}
起到了保存当前线程中的身份验证信息(Authentication
对象)的作用。
使得这个类允许在多线程环境下,将身份验证信息与当前线程关联起来,以便在整个线程执行过程中可以方便地访问和操作这个信息。
getContext()
:获取当前线程中的身份验证信息。通过调用这个方法,可以在任何地方获取到当前线程中的身份验证信息,而不需要显式地传递或者重新获取。
setContext(Authentication context)
:设置当前线程中的身份验证信息。通过调用这个方法,可以将身份验证信息保存到当前线程中,以便后续的操作使用。
clearContext()
:清除当前线程中的身份验证信息。通常在处理完请求或者身份验证过程结束后,需要调用这个方法来清理线程局部变量,以防止内存泄漏或者数据混乱。
————
很常见的操作是:
在业务逻辑中,也就是你可以根据他的角色进行对应的逻辑
获取当前用户ID
获取当前用户信息
获取当前用户权限