ThreadLocal
为 Java 并发安全提供了一种新的思路,它采用线程隔离的机制,每个线程都有拥有自己独立的 ThreadLocal
副本,线程之间互不干扰,每个线程都可以独立地、安全地操作这些变量,而不会影响其他线程。
ThreadLocal
在实际工作中还是有比较多的应用场景,典型的有如下几个:
- 数据库连接或会话信息:很多 ORM 框架,如 Hibernate、Mybatis,都是使用
ThreadLocal
来存储和管理数据库会话的。这样就可以每个线程都有自己独立的的数据库连接,避免了多线程之间的数据库连接冲突。 - 用户身份认证:用户登录成功后,一种常规的做法是是将用户信息存储在 Session 中,如果我们需要获取用户的登录信息,就需要先通过 HttpServletRequest 获取到 Session,然后才能通过 Session 获取到用户信息,同时我们需要在每一个需要用户信息的接口都要加上这个参数,这种方式就显得稍微麻烦了点。换一种思路,我们是否可以将用户的登录信息存储在 ThreadLocal 中呢?当用户登录成功后,我们将用户信息存入到 Token 中返回给前端,当用户调用需要授权的接口时,在 header 中携带 Token ,然后在拦截器中解析 Token,获取用户信息,最后将其存入到 ThreadLocal 中,在使用时我们只需要调用工具类的
get()
就可以获取到用户信息,非常方便,需要注意当请求结束后,记得调用remove()
。 - PageHelper 分页:我们在使用 PageHelper 进行分页时,会用这个方法
PageHelper.startPage(page, limit);
,这个方法就是页码和页码大小等相关信息存储在 ThreadLocal 中,然后在执行分页时读取这些信息。 - 请求追踪(TraceId):在分布式系统中,一个请求可能会跨越多个服务,为了追踪这个请求的整个处理流程,通常会生成一个唯一的 traceId,并在处理请求的每个环节中传递这个 traceId。我们使用
ThreadLocal
存储 traceId ,可以在一个服务的处理过程中保持traceId
不变,即使这个处理过程跨越多个线程或方法调用。 - 日志记录:类似于请求追踪,
ThreadLocal
可以用来在日志记录中保持一些上下文信息(如用户ID,请求ID等),这样可以在整个请求处理流程中轻松地将这些上下文信息添加到日志中,而不需要在每个方法调用中传递这些信息。比如大明哥就喜欢给所有请求都加一个业务流水号 businessNo,然后将其存储在 ThreadLocal,便于打印在日终中,这样就可以通过这个 businessNo 跟踪整个请求日志相关信息了,非常方便。
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。