ThreadLocal原理解析

2021-06-12  本文已影响0人  梦想实现家_Z

为了证明一下只要ThreadLocal没有任何其他强引用,那么经过gc后就会立马被回收,我写了下面这段代码:

public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(
                        () -> {
                            // 创建一个ThreadLocal对象
                            ThreadLocal<String> threadLocal = new ThreadLocal<>();
                            threadLocal.set("hello world");
                            // 让ThreadLocal对象没有任何强引用
                            threadLocal = null;
                            System.gc();
                            // 获取当前线程
                            Thread currentThread = Thread.currentThread();
                            // 可以在这一行打断点,查看currentThread里面的threadLocals对象
                            countDownLatch.countDown();
                        })
                .start();
        countDownLatch.await();
    }
image-20210612140215761.png

如上图所示,gc后referent属性值为null,说明此时Entry中的key已经被回收了,但是value依然存在。

如何处理value的强引用?

可参照以下模版:

ThreadLocal<String> threadLocal = new ThreadLocal<>();
try{
  threadLocal.set("hello world");
    // todo
}finally{
  threadLocal.remove();
}

无论key是强引用还是弱引用,threadLocal都必须要在代码逻辑执行完毕后调用remove()将value的强引用删掉,否则就会导致内存泄漏。
也就是说,ThreadLocal不需要开发者关心key的回收问题,开发者只需要关心自己操作的value的回收问题即可。内部的归内部管理,外部的归外部管理,各司其职。

上一篇下一篇

猜你喜欢

热点阅读