1、提出问题
threadlocal是什么?原理是什么?有什么作用?threadlocal解决了什么问题?
2、源码阅读
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(); }
从源码中可以看出,get()方法做了几件事情
1、先取当前线程t,
2、然后再获得线程内部类 ThreadLocalMap,ThreadLocalMap是一个key-value的数据结构,key是ThreadLocal类型的,
value是object类型的。
3、从ThreadLocalMap中取当前线程的value
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
类比于get()方法,set()方法传递一个value进来,然后将其设置进当前线程的ThreadLocalMap中。
说白了就是每个线程维护自己的静态ThreadLocalMap。线程之间做到互不干扰。
那么同一个线程中定义了两个ThreadLocal对象,会不会覆盖,ThreadLocalMap是根据什么区分不同ThreadLocal对象的值?
ThreadLocal类里有final类型成员变量threadLocalHashCode,每创建一个ThreadLocal对象都会通过静态的nextHashCode新生
成一个HashCode,这个HashCode在value存入ThreadLocalMap的时候会进行key.threadLocalHashCode & (len-1)运算,
得出在Entry数组中的下标。这样就能唯一标识不同的ThreadLocal对象存在ThreadLocalMap中的位置。