在每个线程内部都有一个名为threadLocals的成员变量,该变量的类型为HashMap,其中key为我们定义的ThreadLocal变量的this引用,value则为我们使用set方法设置的值。每个线程的本地变量存放在线程自己的内存变量threadLocals中,如果当前线程一直不消亡,那么这些本地变量会一直存在,所以可能会造成内存溢出,因此使用完毕后要记得调用ThreadLocal的remove方法删除对应线程的threadLocals中的本地变量。
public class ThreadLocalTest { static ThreadLocal<String> localVariable = new ThreadLocal<>(); static void print(String str){ System.out.println(str + ":" + localVariable.get()); localVariable.remove(); } public static void main(String[] args) { Thread threadOne = new Thread(new Runnable() { @Override public void run() { localVariable.set("threadOne local variable!"); print("threadOne"); System.out.println("threadOne remove after :" + localVariable.get()); } }); Thread threadTwo = new Thread(new Runnable() { @Override public void run() { localVariable.set("threadTwo local variable!"); print("threadTwo"); System.out.println("threadTwo remove after :" + localVariable.get()); } }); threadOne.start(); threadTwo.start(); } }
ThreadLocal不支持继承性
public class ThreadLocal { public static ThreadLocal<String> threadLocal = new ThreadLocal<>();public static void main(String[] args) { threadLocal.set("Hello World!"); Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("thead:" + threadLocal.get()); } }); thread.start(); System.out.println("main:" + threadLocal.get()); } }
一个ThreadLocal变量在父线程中被设置值后,在子线程中是获取不到的。根据上节的介绍,这应该是正常现象,因为在子线程thread里面调用get方法时当前线程为thread线程,而这里调用set方法设置线程变量的是main线程,两者是不同的线程,自然子线程访问时返回null。那么有没有办法让子线程能访问到父线程中的值?答案是有。
InheritableThreadLocal类
InheritableThreadLocal继承自ThreadLocal,其提供了一个特性,就是让子线程可以访问在父线程中设置的本地变量。
public class ThreadLocal { public static InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<>(); public static void main(String[] args) { threadLocal.set("Hello World!"); Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("thead:" + threadLocal.get()); } }); thread.start(); System.out.println("main:" + threadLocal.get()); } }