Skip to main content

java thread local 初始化时机

· 3 min read

背景

java 的spring boot 不少地方用到了利用java 的thread local map 来实现线程变量隔离。 想要理解java的相关内容。

实现

核心就在于每次创建线程的对象实例的时候,在线程的初始化时候会把threadlocal map 创建好 , 每个线程一个自己的map , 从而实现线程隔离

文件路径在jdk 的这里 src/java.base/share/classes/java/lang/Thread.java

   /**
* Initializes a virtual Thread.
*
* @param name thread name, can be null
* @param characteristics thread characteristics
* @param bound true when bound to an OS thread
*/
Thread(String name, int characteristics, boolean bound) {
...
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parentMap);
...
}

threadlocal 初始化

threadlocal 有多个入口 ,最后都是通过createMap 初始化ThreadlocalMap , 这个map 由Thread 的实例化对象持有,

核心对象成员: threadLocals . 每个线程自己持有一个map , 这个map的entry是一个weakreference

    /* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
    /**
* Sets the current thread's copy of this thread-local variable
* to the specified value. Most subclasses will have no need to
* override this method, relying solely on the {@link #initialValue}
* method to set the values of thread-locals.
*
* @param value the value to be stored in the current thread's copy of
* this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value);
} else {
createMap(t, value); // 初始化
}
}
    /**
* Variant of set() to establish initialValue. Used instead
* of set() in case user has overridden the set() method.
*
* @return the initial value
*/
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value);
} else {
createMap(t, value); // 初始化
}
if (this instanceof TerminatingThreadLocal) {
TerminatingThreadLocal.register((TerminatingThreadLocal<?>) this);
}
return value;

每个thread 持有一个threadLocals 对象

    /**
* Get the map associated with a ThreadLocal. Overridden in
* InheritableThreadLocal.
*
* @param t the current thread
* @return the map
*/
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}

相关阅读