ThreadLocal

2021-11-10  本文已影响0人  小巨人Vea

ThreadLocal 是什么?
是一个关于创建线程局部变量的类。

每个线程都有一个保存值的 ThreadLocalMap 对象,ThreadLocal 的值就存放在了当前线程的 ThreadLocalMap 成员变量中,所以只能在本线程访问,其他线程不能访问。

public class Thread implements Runnable {
  ...

    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;
 ...
}

从当前线程的ThreadLocalMap中取出当前线程对应的变量的副本【注意,变量是保存在线程中的,而不是保存在ThreadLocal变量中】

363274-20191206104956269-1729288815.png

ThreadLocalMap维护了Entry环形数组,数组中元素Entry的逻辑上的key为某个ThreadLocal对象(实际上是指向该ThreadLocal对象的弱引用),value为代码中该线程往该ThreadLoacl变量实际塞入的值。

从ThreadLocal读一个值可能遇到的情况:根据入参threadLocal的threadLocalHashCode对表容量取模得到 index

ThreadLocal的set方法可能会有的情况。

ThreadLocal内存泄漏问题?
每个thread中都存在一个map, map的类型是ThreadLocal.ThreadLocalMap. Map中的key为一个threadlocal实例. 这个Map的确使用了弱引用,不过弱引用只是针对key. 每个key都弱引用指向threadlocal. 当把threadlocal实例置为null以后,没有任何强引用指向threadlocal实例,所以threadlocal将会被gc回收. 但是,我们的value却不能回收,因为存在一条从current thread连接过来的强引用. 只有当前thread结束以后, current thread就不会存在栈中,强引用断开, Current Thread, Map, value将全部被GC回收。所以得出一个结论就是只要这个线程对象被gc回收,就不会出现内存泄露,但在threadLocal设为null和线程结束这段时间不会被回收的,就发生了我们认为的内存泄露。其实这是一个对概念理解的不一致,也没什么好争论的。最要命的是线程对象不被回收的情况,这就发生了真正意义上的内存泄露。比如使用线程池的时候,线程结束是不会销毁的,会再次使用的就可能出现内存泄露 。(在web应用中,每次http请求都是一个线程,tomcat容器配置使用线程池时会出现内存泄漏问题)

https://www.cnblogs.com/mingfeng002/p/11917883.html

上一篇下一篇

猜你喜欢

热点阅读