ThreadLocal简介
ThreadLocal是线程变量;其中的变量只属于当前线程,线程之间能够隔离,保证了线程安全。同一个ThreadLocal包含的对象在不同线程中有不同的value,这一value只能在同一线程中使用。
ThreadLocal通常在创建时用private static修饰,在同一线程中可以调用此变量。
ThreadLocal工具类编写
class ThreadLocalUtil(){
//利用此threadLocal缓存String类型数据
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void set(String s){
threadLocal.set(s);
}
public static void get(){
threadLocal.get();
}
public static void remove(){
threadLocal.remove();
}
}
利用此工具类可以实现不同方法中对同一ThreadLocal的调用,实现对数据的缓存及获取。
ThreadLocal实现原理
通过ThreadLocal内部静态类ThreadLocalMap来实现对数据的存储。
一个线程中只有一个ThreadLocalMap,其生命周期与该线程一致,线程死亡则ThreadLocalMap消失,ThreadLocalMap中存储ThreadLocal。具体如下:
ThreadLocalMap为一个Map,其key(左边列)是某一ThreadLocal变量的地址,value(右边列)是该ThreadLocal存储的数据(若还未设置则为一个初始值)。
当执行ThreadLocal.set(val)时,方法会先得到当前线程,然后去ThreadLocalMap中找,若此时map为空,则创建一个ThreadLocalMap,并将当前线程和所附的值放入其中;不为空时,找到当前线程的ThreadLocalMap,在其中插入(ThreadLocal,val)。
当执行ThreadLocal,get()方法时,得到当前线程,去对应的ThreadLocalMap中查找当前ThreadLocal,得到其val,若在这之前没有set操作,则会返回一个初始值。
当执行ThreadLocal.remove()方法时,同理前往当前线程的ThreadLocalMap进校remove操作。
ThreadLocal需要注意的问题
内存泄漏:当此threadLocal线程变量没有及时回收时,可能会出现内存泄漏的问题;因此要记得在使用完后进行remove操作
弱引用:ThreadLocalMap对(ThreadLocal,val)的存储,是将其存储为弱引用的entry。entry的key弱引用指向某个ThreadLocal,当使用完毕后,弱引用会自动回收,此时若没有进行remove,则会出现key为null但val仍有值的情况,出现内存泄漏。
强引用:当前Thread指向ThreadLocalMap以及ThreadLocalMap指向ThreadLocacl都为强引用,因此不会被回收。
获取当前线程中所有的ThreadLocal
可以使用反射进校获取:
代码参考:
参考资料:
https://www.csdn.net/tags/MtTaIgzsODQxMzMtYmxvZwO0O0OO0O0O.html