问题描述:
在用户成功登录后,我们在后端某些其它功能模块中需要获取到当前登录用户的信息。
并且需要保证用户信息的安全,除去当前线程外,其它线程无法获取到用户的信息。
解决方法 :
使用threadlocal
保存用户信息,就可以在其它的功能模块中获取到已登录的用户信息。
实现了线程隔离,保证了用户信息安全。
threadlocal存在问题:
threadlocal是存在内存泄漏的问题的,因为每一个Thread维护一个ThreadLocalMap
,key为弱引用的Threadlocal
实例,value为线程变量的副本,是强引用。在Threadlocal
没有被外部强引用的情况下,当垃圾回收时,Threadlocal
就会被清理掉,而此时key被清理掉了,而value不会被清理掉。
这样一来,ThreadLocalMap
中就存在了key为NULL的键值对,永远无法被GC回收,这样长时间累积就会导致内存泄漏。其实Threadlocal
已经考虑到了这样的问题,所以在调用set
、get
和remove
方法时,会清理掉key为NULL的记录。
但即使如此,在使用完用户信息后,还是要手动调用remove
方法移除键值对,避免内存泄漏。
具体使用:
public class UserThreadLocal {
private UserThreadLocal(){}
private static final ThreadLocal<SysUser> LOCAL = new ThreadLocal<>();
public static void put(SysUser sysUser){
LOCAL.set(sysUser);
}
public static SysUser get(){
return LOCAL.get();
}
public static void remove(){
LOCAL.remove();
}
}
测试:
@RestController
@RequestMapping("test")
public class TestController {
@RequestMapping
public Result test(){
SysUser sysUser = UserThreadLocal.get();
System.out.println(sysUser);
return Result.success(null);
}
}