1. 什么是ThreadLocal
ThreadLocal
叫做本地线程变量,全称thread local variable。ThreadLocal的每一个线程都关联一个变量,并且保证每个线程都只能访问自己关联的变量,而且不会影响其他线程的数据。
get()
:获取当前线程的线程的本地变量。如果当前线程没有设置变量,则返回null。set(T value)
:设置当前线程的本地变量。如果当前线程之前已经设置过变量,则会覆盖原来的值。remove()
:移除当前线程的本地变量。这样做可以防止内存泄漏,尤其是在使用线程池等长生命周期线程的情况下。
2. Threadlocal的应用场景
在多线程环境中,有时候需要在线程之间传递一些上下文信息,例如用户身份等信息。如果使用传递参数的方式,则会导致方法参数数量会变多以及在方法调用链上会变得更加繁琐。
所以此场景下,使用ThreadLocal会更加合适,它可以实现方法调用链上的参数透传,也就是每次请求都有一个线程,使得不需要显式地将这些参数信息传递给每个方法调用,避免方法参数多次传递,打破层次间的传递约束。
3. 内存泄露问题
Java内存泄漏是指在程序中,不再使用的对象仍然被保留在内存中,导致内存资源的浪费。这些对象无法被垃圾回收器回收,导致占用的内存不断积累,最终耗尽可用的内存资源。
在使用完ThreadLocal,需要要调用一下remove()方法,这样会防止内存溢出这种情况的发生。因为ThreadLocalMap中使用的key为ThreadLocal为弱引用,而 value 是 强引用。如果ThreadLocal在没有被外部强引用的情况下,key 会被清理掉,而 value 不会被清理掉。导致 value 永远无法被 GC 回收,这个时候就可能会产生内存泄露。
强引用:最常见的引用类型,当对象被强引用关联时,垃圾回收器不会回收该对象,即使在内存不足的情况下。
弱引用:一种非强制性的引用类型,当内存不足时,垃圾回收器会自动回收这些对象,避免内存泄露。