Skip to content

java thread local 初始化时机

Posted on:September 11, 2022 at 09:34 AM

背景

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;
    }

相关阅读