ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,其实意思差不多。可能很多朋友都知道ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
Thread-1中只有一个ThreadLocal.ThreadLocalMap(图中列就是一个ThreadLocal.ThreadLocalMap),而ThreadLocal设置值进去ThreadLocal.ThreadLocalMap是以它本身为key,所以一个ThreadLocal变量,对一个线程只能存储一个对象
Thread-1 | Thread-2 | |
ThreadLocal-1 | <ThreadLocal-1,value> | <ThreadLocal-1,value> |
ThreadLocal-2 | <ThreadLocal-2,value> | <ThreadLocal-2,value> |
ThreadLocal变量存储对象的步骤:
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } |
以上是ThreadLocal的set方法。
1、首先获取当前的线程Thread对象t,通过getMap(t),拿到当前线程的ThreadLocalMap对象,该对象存储在当前线程对象的threadLocals属性。
2、如果当前线程已有对应的ThreadLocalMap 就,将当前的ThreadLocal对象作为key,设置的value做为value设置到ThreadLocalMap中。
3、如果当前线程没有ThreadLocalMap对象则,创建一个ThreadLocalMap对象,以当前ThreadLocal对象为key,设置的value做为value设置到ThreadLocalMap中.并将
这个ThreadLocalMap赋值给当前Thread对象的threadLocals属性。
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(); } |
1、首先获取当前的线程Thread对象t,通过getMap(t),拿到当前线程的ThreadLocalMap对象,该对象存储在当前线程对象的threadLocals属性。
2、以当前的ThreadLocal对象为key,获取ThreadLocalMap中的Entry对象,获取entry对象的 value属性,并返回。