- ThreadLocalMap类,也就是Thread.threadLocals
- ThreadLocalMap类是每个线程Thread类里面的变量,里面最重要的是一个键值对数组Entry[] table,可以认为是一个Map,键值对:
- 键:这个ThreadLocal
- 值:实际需要的成员变量,比如User或者SimpleDateFormat
ThreadLocalMap虽然类似HashMap但是处理处理Hash冲突略有不同
ThreadLocalMap采用的是线性探测法,也就是如果发生Hash冲突,就继续寻找下一个空位,而不是采用链表拉链
ThreadLocal两种使用场景殊途同归
- 通过源码分析可以看出,setInitialValue和直接set最后都是利用map.set()方法来设置值
- 也就是说,最后都会对应到ThreadLocalMap的一个Entry,只是起点和入口不一样
Thread类:
public class Thread implements Runnable{
/**声明ThreadLocalMap类对象,它可以存储多个ThreadLocal静态常量的哈希标记
* 而一个ThreadLocal静态常量可以维护一个线程内变量
* 即一个ThreadLocalMap类对象可以存储多个线程内变量,而这些变量的key就是它们各自的维护者:ThreadLocal静态常量的哈希标记
* **/
ThreadLocal.ThreadLocalMap threadLocals =null;
/**返回对当前执行的线程对象的引用,“native”表示该方法是由c语言编写的底层方法*/
public static native Thread currentThread();
@Override
public void run() {
//省略
}
}
ThreadLocal类:
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**原理,类似于访问者模式,ThreadLocal是访问者,Thread是被访问者。
* ThreadLocal访问的是Thread的局部变量ThreadLocalMap
* 当使用ThreadLocal维护变量时,ThreadLocal为每个【使用该变量的线程】提供独立的变量副本,
* 所以每个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本.
**/
public class ThreadLocal<T> {
//线程的内部变量ThreadLocalMap对象 对ThreadLocal对象所维护的 线程内变量 的一种哈希标记
private final int threadLocalHashCode = new AtomicInteger().getAndAdd(0x61c88647);
//定义ThreadLocalMap内部类
static class ThreadLocalMap{
//源码逻辑是一种哈希映射,这里暂时用Map替代
//以当前ThreadLocal对象的标记 作为key
Map<Integer,Object> m = new HashMap<Integer,Object>();
public ThreadLocalMap(ThreadLocal threadLocal, Object firstObj) {
//--省略
}
void set(ThreadLocal threadLocal, Object value){
m.put(threadLocal.threadLocalHashCode, value);
}
Object get(ThreadLocal threadLocal){
return m.get(threadLocal.threadLocalHashCode);
}
void remove(){}
}
//访问的是Thread的局部变量ThreadLocalMap,并为其注入值
public void set(T t){
//获取当前线程,然后获取到当前线程里面的ThreadLocalMap引用
ThreadLocalMap map = Thread.currentThread().threadLocals;
//以当前ThreadLocal对象为参数
map.set(this,t);
}
//访问的是Thread的局部变量ThreadLocalMap,并获取其值
public T get(){
ThreadLocalMap map = Thread.currentThread().threadLocals;
if(null!=map){
return (T) map.get(this);
}
//如果为空,则初始化(创建并设置对象副本)
return setInitialValue();
}
private T setInitialValue(){
Thread thread = Thread.currentThread();
ThreadLocalMap map = thread.threadLocals;
if (map != null)
map.set(this, null);
else
map = new ThreadLocalMap(this, null);
return null;
}
}