提供线程内部的局部变量,各个线程的局部变量值是相互独立的。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
结合代码理解
public class TestThreadLocal {
private static final ThreadLocal<Integer> value = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
}
};
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
new Thread(new MyThread(i)).start();
}
}
static class MyThread implements Runnable {
private int index;
public MyThread(int index) {
this.index = index;
}
public void run() {
System.out.println( "线程" + index + "的初始value:" + value.get());
for (int i = 0; i < 5; i++) {
value.set(value.get() + i);
}
System.out.println("线程" + index + "的计算后的value:" + value.get());
}
}
运行结果
线程1的初始value:0
线程1的计算后的value:1
线程1的计算后的value:2
线程1的计算后的value:3
线程1的计算后的value:4
线程1的计算后的value:5
线程2的初始value:0
线程2的计算后的value:1
线程2的计算后的value:2
线程2的计算后的value:3
线程2的计算后的value:4
线程2的计算后的value:5
线程0的初始value:0
线程0的计算后的value:1
线程0的计算后的value:2
线程0的计算后的value:3
线程0的计算后的value:4
线程0的计算后的value:5
核心函数
initialValue
protected T initialValue() { return null; }
设置初始数据,通常需要重写该方法来设置。
get()
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) return (T)e.value; } return setInitialValue(); } ThreadLocalMap getMap(Thread t) { return t.threadLocals; }
获取当前线程的关联数据,若没有关联数据,则返回初始值。
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 getMap(Thread t) { return t.threadLocals; } void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }
设置当前线程的关联数据。首先根据当前线程获取一个Map,Map为null则创建一个Map,用当前ThreadLocal的引用作为key,关联数据作为value存储在Map中。
每个Thread维护一个ThreadLocalMap映射表,这个映射表的key是ThreadLocal本身,value是需要存储的Object。