ThreadLocal的常用场景

1. Web应用中的过滤器

ThreadLocal非常适合在我们的web应用中使用,当web请求进来的时候,我们就可以将一些数据放入到threadLocal中,这样后续所有的相关业务,都可以直接拿到这个值。

常见的就是过滤器,我们在业务中,当小程序的用户发起请求的时候,会将用户的基本信息rpc查询出来后,放入threadLocal,这样方便了后续进行处理。使用完成后,再调用remove进行清除。

一个线程中出现的所有ThreadLocal都是保存在map中的,所以是一个map结构,通过ThreadLocal的key引用来获取值。

2. 代替参数传递

当我们在写API接口的时候,通常Controller层会接受来自前端的入参,当这个接口功能比较复杂的时候,可能我们调用的Service层内部还调用了很多其他方法。

通常情况下,我们会在每个调用的方法上加上需要传递的参数。但是如果我们将参数存入ThreadLocal中,那么就不用显式的传递参数了,而是只需要ThreadLocal中获取即可。

这个场景其实使用的比较少,一方面显式传参比较容易理解,另一方面我们可以将多个参数封装为对象去传递。

3. 拦截器中解析信息

用户信息会保存在Session或者Token中。这个时候,我们如果使用常规的手段去获取用户信息会很费劲。

拿Session来说,我们要在接口参数中加上HttpServletRequest对象,然后调用getSession方法,且每一个需要用户信息的接口都要加上这个参数,才能获取Session,这样实现就很麻烦了。

我们需要使用ThreadLocal,我们会选择在拦截器的业务中,获取到保存的用户信息,然后存入ThreadLocal,那么当前线程在任何地方如果需要拿到用户信息都可以使用ThreadLocal的get方法。

3.1 具体用法

当用户登录后,会将用户信息存入Token中返回前端,当用户调用需要授权的接口时,需要在header中携带Token,然后拦载器中解析Token,获取用户信息,调用自定义的类存ThreadLocal中,当请求结束的时候,将ThreadLocal存储数据清空,中间的过程无需在关注如何获取用户信息,只需要使用工具类的get方法即可。

4. 资源分割

4.1 解决的问题

在Spring的Web项目中,我们通常会将业务分为Controller层,Service层,Dao层,我们都知道@Autowired注解默认使用单例模式,那么不同请求线程进来之后,由于Dao层使用单例,负责数据库连接的Connection也只有一个,如果每个请求线程都去连接数据库,那么就会造成线程不安全的问题,Spring是如何解决这个问题的呢?

4.2 解决方案

在Spring项目中Dao层中装配的Connection是线程安全的,其解决方案就是采用ThreadLocal方法,当每个请求线程使用Connection的时候,都会从ThreadLocal获取一次,如果为null,说明没有进行过数据库连接,连接后存入ThreadLocal中,如此一来,每一个请求线程都保存有一份自己的Connection,于是便解决了线程安全问题

4.3 设计理念

ThreadLocal在设计之初就是为解决并发问题而提供一种方案,每个线程维护一份自己的数据,达到线程隔离的效果。

参考资料:【大厂面试题】ThreadLocal的常用场景?

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadLocal常用方法包括get()、set()、initialValue()等。 get()方法用于获取当前线程的ThreadLocal变量的值。通过调用ThreadLocal的get()方法,可以获取到当前线程所存储的变量值。 set()方法用于设置当前线程的ThreadLocal变量的值。通过调用ThreadLocal的set()方法,可以将一个值设置到当前线程的ThreadLocal变量中。 initialValue()方法用于为ThreadLocal变量指定一个初始值。ThreadLocal的initialValue()方法默认返回null,但可以通过重写该方法来指定一个自定义的初始值。在Java 8中,可以使用Supplier函数接口更加简化地指定初始值。 总结起来,ThreadLocal常用的方法有get()、set()和initialValue()。通过这些方法,可以在多线程环境下实现线程私有的变量存储和获取。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ThreadLocal常用场景](https://blog.csdn.net/qq_46130027/article/details/130191786)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ThreadLocal常用方法浅析、使用场景及注意事项](https://blog.csdn.net/qq_42742861/article/details/90649837)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值