线程Thread存在一个字段,它是ThreadLocalMap,它和Map类似,key是ThreadLocal对象,值是设置的值。
get() 获取当前线程,获取当前线程持有的ThreadLocalMap,【果map是null,则调用初始化逻辑:获取当前线程,获取当前线程持有的ThreadLocalMap,如果map是null则以ThreadLocal为key,初始化值为val保存map,如果map不是null,则创建ThreadLocalMap,key为ThreadLocal,val为初始化值,最后返回初始化值】,【如果不是null,则map以ThreadLocal为key进行get出值返回】。
set(T value) 获取当前线程,获取当前线程持有的ThreadLocalMap,如果map是空使用key为ThreadLocal值为设置的值创建ThreadLocalMap,如果非空map进行set键为ThreadLocal,值为设置的值。
remove()获取当前线程,获取当前线程的ThreadLocalMap,map移除key为ThreadLocal的Entry.
ThreadLocal内存泄漏问题:由于线程Thread持有对ThreadLocalMap的引用,如果线程没有被GC回收,那么ThreadLocalMap也不会被回收,其设置的val也不会被回收导致内存泄漏。如果线程被回收,或者使用ThreadLocal的remove方法删除保存的值,则可以避免。
应用示例
package cn.mn.com;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
public class T2 {
static private ThreadLocal<String> stl=new ThreadLocal<String>(){
protected String initialValue() {
return "A0";
}
};
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(stl.get());
stl.set("A1");
System.out.println(stl.get());
stl.remove();
System.out.println(stl.get());
}
}).start();
LockSupport.parkNanos((TimeUnit.SECONDS.toNanos(2)));
System.out.println(stl.get());
}
}