ThreadLocal的使用与思考

一、什么是ThreadLocal:
ThreadLocal提供了线程本地变量,它可以保证访问到的变量属于当前线程,每个线程都保存了一个变量副本,每个线程的变量都不同。ThreadLocal相当于提供了一种线程隔离,将变量与线程相绑定。
ThreadLocal适用于在多线程的情况下,可是实现传递数据,实现线程隔离

二、Threadlocal 核心API:
1.set 设置当前线程绑定的局部变量
2.get 获取当前线程绑定的局部变量
3.remove 移除当前线程绑定的变量

Threadlocal简单用法

public class Test {
    private static ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            threadLocal.set("值");
            System.out.println("成功设置threadLocal");

        });
        thread.start();
        thread.join();
        System.out.println(Thread.currentThread().getName() + "," + threadLocal.get());
    }
}

子线程在ThreadLocal中存放局部变量,但是获取的时候是主线程,所以无法获取
三、Threadlocal 与Synchronized
1.共同特征:都可以解决线程安全问题
2.ThreadLocal占内存、Synchronized不是很占内存
Synchronized 当多个线程同时共享到同一个全局变量的时候,只能有一个线程对该变量做修改操作,缺陷是效率非常低,以时间换空间
ThreadLocal 每个线程都有独立的缓存的局部变量,以空间换时间的方式提高效率

四、Threadlocal原理分析
1.在每个线程中都有自己独立的ThreadlocalMap对象
2.如果当前线程对应的ThreadlocalMap对象为空的情况下,就会创建该ThreadlocalMap对象,并且赋值键值对
key为当前new ThreadLocal()对象,value就是为object变量值
在这里插入图片描述
五、Threadlocal产生内存泄漏问题
因为每个线程都有自己独立的ThreadLocalMap对象,key为ThreadLocal,value 是为变量值。key为ThreadLocal 作为Entity对象的key,为弱引用,当ThreadLocal 指向为null的时候,Entity对象中的key变为null,该对象一直无法被垃圾回收机制回收,一直占有系统的内存,有可能会发生内存泄漏问题。
Threadlocal内存泄漏的根本原因产生于ThreadLocalMap与我们当前线程的生命周期一样,如果没有手动删除的情况下,就有可能发生内存泄漏问题

六、如何防御Threadlocal内存泄漏问题
1.可以自己调用remove方法将不要的数据移除避免内存泄漏的问题,
2. 每次在做set方法的时候会清楚之前 key为null

public class Test {
    private static ThreadLocal threadLocal = new ThreadLocal<String>();
    public static void main(String[] args) {
        threadLocal.set("值");
        threadLocal.remove();
        threadLocal = null;
        System.gc();
        Thread thread = Thread.currentThread();
        threadLocal.get();
    }
}

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页