ThreadLocal 线程本地变量:
用于存储和共享当前线程内的内容,而非所有线程。即相当于我们家里的东西,这东西对我们自己家人是完全共享的,谁都可以用。但是别的外人是不能够看到和使用的,但别的家庭也有自己的东西。
我们现在有个类A,在单个线程中内容保持不变,但在不同线程中内容又都不一样。这种情况我们就可以使用ThreadLocal。
如果类A被所有线程共享则导致并发问题。如果给每个调用都重新创建类A,又会导致线程内冗余,无形占用内存,增大压力。
通过以上的图可以看到,同样的调用在不同的线程中会调用到自己需要的内容。
ThreadLocal解析:
ThreadLocal<T>类有一个内部类ThreadLocalMap,ThreadLocal隶属于package java.lang, 而我们常用的Thread也隶属于package java.lang.
Thread 内部有个变量 ThreadLocal.ThreadLocalMap threadlocals= null.
ThreadLocalMap内部是一个Entry[]数组,其中key用于存储thread的实例 this,也就是 hash值,value就是我们的泛型T。
从以上可知,threadLocal这个类本身并不存储任何值,而是调用 this = Thread.currentThread();获取当前线程的实例对象。
实例对象内部有个属性 ThreadLocalMap map = this.threadlocals;即 我们的值是存储在Thread.treadlocalMap中。
ThreadLocal使用:
在connection连接池或者session中使用较多。
/** * 本地threadlocal的内容保存 * @description: * @author DennyZhao * @date: 2018年9月3日 * @version : 1.0 */public class MacThreadLocal { /** 静态threadlocal变量 **/ private static ThreadLocalthreadlocalName = new ThreadLocal (); private static ThreadLocal threadlocalID = new ThreadLocal (); private static ThreadLocal
main方法:
/** * 本地线程变量测试类 * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { threadLocal.set("k123", "v456"); threadLocal.print(); Thread t1 = new Thread(){ @Override public void run() { threadLocal.set("k567", "v890"); threadLocal.print(); super.run(); } }; t1.start(); t1.join(100); threadLocal.print(); }
结果:
--ID---1--NAME---main--Map---key:k123 value:v456--ID---9--NAME---Thread-0--Map---key:k567 value:v890--ID---1--NAME---main--Map---key:k123 value:v456