源码分析:
ThreadLocal中定义了ThreadLocalMap静态内部类,该内部类中又定义了Entry内部类。
ThreadLocalMap定了 Entry数组。
Set方法:
Get方法:
Thread中定义了两个ThreaLocalMap成员变量:
Spring使用ThreadLocal解决线程安全问题
我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全的“状态性对象”采用ThreadLocal进行封装,让它们也成为线程安全的“状态性对象”,因此有状态的Bean就能够以singleton的方式在多线程中正常工作了。
一般的Web应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程,如图
这样用户就可以根据需要,将一些非线程安全的变量以ThreadLocal存放,在同一次请求响应的调用线程中,所有对象所访问的同一ThreadLocal变量都是当前线程所绑定的。
内存泄漏原因:
ThreadLocal其实是与线程绑定的一个变量,如此就会出现一个问题:如果没有将ThreadLocal内的变量删除(remove)或替换,它的生命周期将会与线程共存。通常线程池中对线程管理都是采用线程复用的方法,在线程池中线程很难结束甚至于永远不会结束,这将意味着线程持续的时间将不可预测,甚至与JVM的生命周期一致。举个例字,如果ThreadLocal中直接或间接包装了集合类或复杂对象,每次在同一个ThreadLocal中取出对象后,再对内容做操作,那么内部的集合类和复杂对象所占用的空间可能会开始持续膨胀。
知识来源:
【并发与线程】ThreadLocal的底层原理_哔哩哔哩_bilibili
【并发与线程】ThreadLocal的原理的使用场景_哔哩哔哩_bilibili
【并发与线程】ThreadLocal内存泄露问题,如何避免_哔哩哔哩_bilibili
史上最全ThreadLocal 详解(一)_倔强的不服的博客-CSDN博客
史上最全ThreadLocal 详解(二)_多个threadlocal_倔强的不服的博客-CSDN博客