ThreadLocal 的使用和内存泄漏问题
ThreadLocal 解决了什么问题、会引发什么问题,这是一个经典话题。很多人用 ThreadLocal 存储用户上下文,却忽略了内存泄漏的风险。本文从原理到内存泄漏的处理方式都覆盖到。
先建立一个最小案例
并发问题不要一开始就上复杂业务。可以先准备一个计数器场景:
class Counter { |
这段代码在单线程里没有问题,但多线程同时调用 add() 时,count++ 不是原子操作,结果可能比预期小。
正确处理思路
如果只是简单计数,可以用 AtomicInteger:
class Counter { |
如果临界区里有多步业务逻辑,可以考虑 synchronized 或 ReentrantLock。选择时不要只看性能,先看代码是否清晰、锁范围是否足够小、异常时是否能释放锁。
排查建议
线上并发问题通常不稳定复现。可以先看日志里是否有重复请求、状态覆盖、库存扣减异常,再用压测或单元测试构造并发场景。
核心要点
ThreadLocal 为每个线程提供独立的变量副本
底层使用 ThreadLocalMap 存储,key 是弱引用
内存泄漏的原因:ThreadLocal 被回收,但 Entry 仍然引用着 value
解决方案:使用完毕后调用 remove() 方法
总结
ThreadLocal 是一个强大的工具,但需要谨慎使用。在实际项目中,结合 try-finally 块确保资源被正确清理,可以有效避免内存泄漏问题。