ThreadLocal简单来说就是可以实现线程之间变量隔离,每个线程对于变量操作不影响其他变量。
使用示例
public class TestThreadLocal {
public static void main(String args[]){
ThreadLocal<Integer> tl = new ThreadLocal<Integer>(){
public Integer initialValue() {
//return new Person();
return 123;
}
};
tl.set(0);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("t1:"+tl.get());
tl.set(111);
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2:"+tl.get());
tl.set(222);
}
});
t2.start();
System.out.println("main:"+tl.get());
}
}
输出
main:0
t1:123
t2:123
ThreadLocal使用十分简单,我们可以从源码的角度来看一下。以下是ThreadLocal的set方法。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
每个线程都有一个ThreadLocalMap,ThreadLocalMap是用来保存这个线程的所有ThreadLocal,Map的key是ThreadLocal对象本身,value就是Threadlocal的值。
ThreadLocal.ThreadLocalMap threadLocals = null;
再来看一下get方法,也是获取当前的Thread线程对象,然后在通过Thread还拿到ThreadLocalMap,然后传入this即Thread对象本身作为key取出保存的值。如果没有则调用setInitialVal()方法,setInitailVal()方法里面会调用initailValue()方法获取默认值然后在set进ThreadLocal中。
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
重写initialValue方法,线程第一次访问时就会返回初始值
protected T initialValue() {
return null;
}