ThreadLocal
是 Java 提供的一个工具,用来在多线程环境下保存每个线程自己的“私有数据”。它可以让不同线程保存和使用自己的变量副本,不会互相干扰。
在 Web 系统,你可能需要保存一些用户信息(比如用户 ID)并在多个地方使用,而又不希望这些信息被其他线程看到。ThreadLocal
可以帮你把这些信息绑定到当前线程上,让它随时可用。
在 Web 开发中,当每个请求到来时,后端需要知道“当前用户是谁”。可以使用 ThreadLocal
保存用户信息。
以获取当前用户id为例
登录流程:
员工登录成功后会生成JWT令牌并响应给前端:
//登录成功后,生成jwt令牌
Map<String, Object> claims = new HashMap<>();
claims.put(JwtClaimsConstant.EMP_ID,employee.getId());
String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(),jwtProperties.getAdminTtl(),claims);
后续请求中,前端会携带JWT令牌,通过JWT令牌可以解析出当前登录员工id:
ThreadLocal 并不是一个Thread,而是Thread的局部变量。
ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
ThreadLocal常用方法:
•
public
void set(
T
value)
设置当前线程的线程局部变量的值
•
public
T
get()
返回当前线程所对应的线程局部变量的值
•
public void remove()
移除当前线程的线程局部变量
注意:客户端发送的每次请求,后端的Tomcat服务器都会分配一个单独的线程来处理请求
已经封装了 ThreadLocal 操作的工具类:
package com.sky.context;
public class BaseContext {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setCurrentId(Long id) {
threadLocal.set(id);
}
public static Long getCurrentId() {
return threadLocal.get();
}
public static void removeCurrentId() {
threadLocal.remove();
}
}
在拦截器中解析出当前登录员工id,并放入线程局部变量中: