上下文信息(记录用户信息实现全局操作)"/>
通过ThreadLocal记录上下文信息(记录用户信息实现全局操作)
😊 @ 作者: 一恍过去 💖 @ 主页: 🎊 @ 社区: Java技术栈交流 🎉 @ 主题: 通过ThreadLocal记录上下文信息(记录用户信息实现全局操作) ⏱️ @ 创作时间: 2022年03月15日
ThreadLocal为每一个线程都提供了变量的副本,并且变量在整个线程的生命周期有效,形成了线程与线程之间的隔离,只有同一个线程才能操作变量,是一种”以空间换时间”的形式,可以用来记录一些上下文数据。
ThreadLocal内部通过Map来储存每一个线程的变量副本,map的key就是threadLocal,value就是我们set的那个值,每次线程在get的时候,都从自己的变量中取值,所以肯定就不存在线程安全问题。
使用ThreadLocal后,一定要注意手动remove()否则会造成OOM异常。
ThreadLocal是Java中的一个线程级别的变量,它可以在同一线程内共享数据,并且每个线程都有自己独立的副本。ThreadLocal通常被用于在多线程环境下记录和管理线程的上下文信息。
使用ThreadLocal可以解决多线程环境下的上下文传递和数据共享的问题,它提供了以下主要功能:
上下文隔离:
每个线程可以通过ThreadLocal独立存储和访问自己的数据,不同线程之间的数据互相隔离,避免了线程间数据的冲突和竞争条件。线程安全:
ThreadLocal提供了线程级别的数据副本,每个线程都可以独立地操作自己的数据,无需考虑并发访问的同步问题。这样可以简化并发编程的复杂性,并提高程序的性能。线程上下文传递:
在多线程环境中,可能需要在不同的方法或组件中传递上下文信息,例如用户认证信息、请求跟踪ID等。ThreadLocal可以在同一线程内共享上下文信息,而无需显式传递参数。
使用ThreadLocal的一般流程如下:
- 在需要存储上下文信息的地方,创建一个ThreadLocal对象,并指定存储的数据类型。
- 使用ThreadLocal的set()方法将数据存储到当前线程的ThreadLocal副本中。
- 在其他需要访问上下文信息的地方,使用ThreadLocal的get()方法获取当前线程的ThreadLocal副本中存储的数据。
- 最后,在使用完ThreadLocal存储的数据后,应当调用remove()方法清理ThreadLocal中的数据,避免内存泄漏。
需要注意的是,虽然ThreadLocal可以在同一线程内共享数据,但它并不是解决多线程并发访问共享数据的方案,而是用于解决线程内上下文信息的传递和隔离。在多线程共享数据的场景下,仍需要考虑并发访问的同步和线程安全性。
场景如下:
- 记录每次请求用户信息
ThreadLocal代码:
public class RequestHolder {private static final ThreadLocal<SysUser> userHolder = new ThreadLocal<SysUser>();public static void setUser(SysUser sysUser) {userHolder.set(sysUser);}public static SysUser getUser() {return userHolder.get();}public static void remove() {userHolder.remove();}
}
应用流程:
以下流程部分使用伪代码
表示
1、拦截器获取用户信息
2、记录到ThreadLocal中
3、使用时通过get()方法获取值
// 1、拦截器获取用户信息
// 2、记录到ThreadLocal中
@Component
public class AuthenticationHandlerInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.debug("进入拦截器,URL:{}", request.getServletPath());// 加入用户全局信息RequestHolder.setUser(userInfo);return true;}........
}// 3、使用时通过get()方法获取值
@RestController
@RequestMapping
public class Controller {.....@GetMapping("/test")public String test() {// 从ThreadLocal获取数据RequestHolder.getUserId();return "访问成功";}.....
}
更多推荐
通过ThreadLocal记录上下文信息(记录用户信息实现全局操作)
发布评论