ThreadLocal原理
首先多线程访问同一个共享变量特别容易出现数据出错,为了保证线程安全,需要做一些同步的措施,同步的措施一般是加锁,有没有一种方式当访问这个变量时,会变成线程内部自己的变量,ThreadLocal就可以做这件事。
其实ThreadLocal可以理解为一个工具,线程真正调用ThreadLocal存数据其实数据是存储在ThreadLocal类中:threadLocals和inheritableThreadLocals中的。这两个变量时一个map类型的,其中key存的是当前调用这个ThreadLocal的线程也就是this,value是要传入的值。默认情况下每个线程中的这两个变量都为Null,也只有当前线程调用ThreadLocal的set或get才会创建它。下面贴出set和get及remove的源码,画一个图方便理解。
public T get() {
Thread var1 = Thread.currentThread();
ThreadLocal.ThreadLocalMap var2 = this.getMap(var1);
if (var2 != null) {
ThreadLocal.ThreadLocalMap.Entry var3 = var2.getEntry(this);
if (var3 != null) {
Object var4 = var3.value;
return var4;
}
}
//如果ThreadLocalMap为空就重新建一个
return this.setInitialValue();
}
public void set(T var1) {
Thread var2 = Thread.currentThread();
ThreadLocal.ThreadLocalMap var3 = this.getMap(var2);
if (var3 != null) {
var3.set(this, var1);
} else {
this.createMap(var2, var1);
}
}
public void remove() {
ThreadLocal.ThreadLocalMap var1 = this.getMap(Thread.currentThread());
if (var1 != null) {
var1.remove(this);
}
}
总结
在每个线程内部都有一个threadlocals变量,该变量为HashMap,其中key为调用的线程,value为set设置的值,如果线程一直不消亡,本地变量就一直存在,容易引发内存溢出,所以当我们使用完毕后记得调用ThreadLocal的remove方法删除对应本地变量。