ThreadLocal其实是Java中的一个类,作用就是将一个变量和当前线程绑定,这样这个变量就是线程安全的,且在这个线程的任意方法中都可以操作此变量;
此类的设计看源码就可以了解,ThreadLocal有点工具类的样子,实际数据是存放在它定义的内部类ThreadLocalMap,此类又有一个Entry内部类,此类是弱引用类中的,而ThreadLocalMap类的引用是定义在Thread里的,总结就是:ThreadLocal只定义了类但是数据还是绑定在Thread中,操作是放在ThreadLocal里,如get set remove方法,而方法的内部还是处理当前线程对象的ThreadLocalMap对象里的数据
一般使用如下及验证弱引用作用如下:
public class ThreadLocalHolder {
public ThreadLocal<String> threadLocal2 = new ThreadLocal<>();
}
public class Main {
private static ThreadLocal<String> threadLocal1 = new ThreadLocal<>();
public static void main(String[] args) {
Thread thread = Thread.currentThread();
threadLocal1.set("String"); // debug 会看到thread对象的threadLocals属性里多了一个threadLocal1的key,且值为String
System.out.println(threadLocal1.get()); // 这里会输出 String
threadLocal1 = null; // 这里让类变量tl为null,
System.gc(); // 触发gc,因为前面tl=null,也就是类变量threadLocal1的引用已经不指向堆里的threadLocal1对象,而threadLocal1对象的 thread里的threadLocals属性里的table数组的Entry类的key还指向堆里的threadLocal1对象,但此引用为弱引用,所以此次gc后,thread的threadLocals里的threadLocal1的key就变成null了,但是value还在,这也是 ThreadLocal里 弱引用设计的目的
System.out.println(thread);
// 下面的例子是 ThreadLocal是一个类里的成员变量,这个成员变量在方法中定义
// 方法执行完,ThreadLocal变量就自动回收,只留下thread的threadLocals里的table数组
// 的Entry类的key引用ThreadLocal变量的堆内地址,而这个引用是弱引用,gc后,这个引用也会
// 消失,那ThreadLocal的堆内存储就会被释放
test();
System.out.println("123");
System.gc();
System.out.println("123");
}
public static void test() {
Thread thread = Thread.currentThread();
ThreadLocalHolder threadLocalHolder = new ThreadLocalHolder();
threadLocalHolder.threadLocal2.set("Long");
}
}
内存结构图如下,当threadLocal1=null,强引用就没了,堆里的threadLocal1变量就只有虚引用,那就会在下次gc的时候被回收了

本文详细介绍了Java中的ThreadLocal类,它用于创建线程安全的局部变量。通过源码分析,展示了ThreadLocal如何将变量存储在Thread对象的ThreadLocalMap中,以及弱引用在内存管理中的作用。示例代码演示了ThreadLocal的使用和弱引用清理过程,帮助理解其内存回收机制。

4533

被折叠的 条评论
为什么被折叠?



