作用
保证共享变量线程安全
原理
通过为每个线程创建资源备份,使得线程之间不再竞争唯一的资源
解释
public class ExePool {
public static void main(String[] args) {
final ThreadLocal<String> stringThreadLocal = ThreadLocal.withInitial(() -> "");
final ThreadLocal<Integer> integerThreadLocal = ThreadLocal.withInitial(() -> 1);
final Thread thread = new Thread(() -> {
System.out.println(Thread.currentThread().getName());
stringThreadLocal.set("StringValue");
integerThreadLocal.set(100);
stringThreadLocal.get();
integerThreadLocal.get();
}, "thread-name");
thread.start();
}
}
这段代码的执行后的结构如下图:
当栈中的ThreadLocal置为null后,堆中的实例会被垃圾回收。此时ThreadLocalMap中Entry的key指向null,Entry的value指向的是实例。如果线程被回收了,那么ThreadLocalMap也会被回收,不会造成内存泄漏。如果用到了线程池,那么核心线程就可能不被回收,造成Entry中的key为null,value不是null的情况,此时的value就是泄露的内存,释放不了,也无法使用。
如果有多个线程,执行后结构如下:
public class ExePool {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
final ThreadLocal<String> stringThreadLocal = ThreadLocal.withInitial(() -> "");
final ThreadLocal<Integer> integerThreadLocal = ThreadLocal.withInitial(() -> 1);
final Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName());
stringThreadLocal.set("StringValue");
integerThreadLocal.set(100);
stringThreadLocal.get();
integerThreadLocal.get();
}, "aaaa");
thread1.start();
final Thread thread2 = new Thread(() -> {
System.out.println(Thread.currentThread().getName());
stringThreadLocal.set("StringValue");
integerThreadLocal.set(100);
stringThreadLocal.get();
integerThreadLocal.get();
}, "bbbb");
thread2.start();
}
}