面试官再问你 ThreadLocal,就这样狠狠 “怼” 回去!

本文详细探讨了ThreadLocal的使用,包括常见应用场景如日志增强、缓存、数据库读写分离和数据传递。同时,解释了ThreadLocal的原理,强调了避免跨线程传递、及时remove以防止内存泄露的重要性,并介绍了性能优化和InheritableThreadLocal在子线程数据传递的角色。此外,还提及了线程池中ThreadLocal数据传递的挑战和解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文大纲

  1. 用过ThreadLocal吗?在什么场景下会使用ThreadLocal
  2. 讲讲ThreadLocal的原理吧!
  3. 使用ThreadLocal有什么需要注意的吗?
  4. 有什么方式能提高ThreadLocal的性能吗?
  5. 如何将ThreadLocal的数据传递到子线程中?
  6. 线程池中如何实现ThreadLocal的数据传递?

用过ThreadLocal吗?在什么场景下会使用ThreadLocal。

这个回答一定要足够自信:必须用过啊,无论是在平时的业务开发过程中会用到,其他很多三方框架中也都用到了ThreadLocal。

如果你回答没用过,很有可能就凉凉了,因为ThreadLocal在很多场景都能用到,假如实在没用过也不要没信心,看完这篇文章你就知道如何回答了。

场景一:ThreadLocal+MDC实现链路日志增强

日志增强之前也写过一篇文章,讲解了实现的功能,细节没有讲,可以看看下面这篇文章了解。

文章:有了链路日志增强,排查Bug小意思啦!

比如我们需要在整个链路的日志中输出当前登录的用户ID,首先就得在拦截器获取过滤器中获取用户ID,然后将用户ID进行存储到ThreadLocal。

然后再层层进行透传,如果用的Dubbo,那么就在Dubbo的Filter中进行传递到下一个服务中。问题来了,在Dubbo的Filter中如何获取前面存储的用户ID呢?

答案就是ThreadLocal。获取后添加到MDC中,就可以在日志中输出用户ID。

场景二:ThreadLocal实现线程内的缓存,避免重复调用

缓存这块就不重复讲了,之前有单独写过文章,大家直接看之前的文章就可以了。

文章:简直骚操作,ThreadLocal还能当缓存用

场景三:ThreadLocal实现数据库读写分离下强制读主库

首先你的项目中要做了读写分离,如果有对读写分离不了解的同学可以查看这篇文章:读写分离

某些业务场景下,必须保证数据的及时性。主从同步有延迟,可以使用强制读主库来保证数据的一致性。

在Sharding JDBC中,有提供对应的API来设置强制路由到主库,具体代码如下:

HintManager hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();

HintManager中就使用了ThreadLocal来存储相关信息。这样就可以实现在业务代码中设置路由信息,在底层的数据库路由那块获取信息,实现优雅的数据传递。

public final class HintManager implements AutoCloseable {
    private static final ThreadLocal<HintManager> HINT_MANAGER_HOLDER = new ThreadLocal();
    // ...............
}

场景四:ThreadLocal实现同一线程下多个类之间的数据传递

在Spring Cloud Zuul中,过滤器是必须要用的。用过滤器我们可以实现权限认证,日志记录,限流等功能。

过滤器有多个,而且是按顺序执行的。过滤器之前要透传数据该如何处理?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值