ThreadLocal,存储线程内部的数据,线程独享,没有线程安全问题,它是如何做到这些的呢?原因就是数据存储在Thread实例中,每一个Thread的实例拥有ThreadLocal.ThreadLocalMap threadLocals 成员,该成员是包共享的。ThreadLocal的set方法把数据存储在当前线程的threadLocals map中,保证每个线程数据的独立。
Thread 代码:
/* ThreadLocal values pertaining to this thread * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal set 代码:
/** * 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); }
ThreadLocal的初始化化方法: protected T initialValue()
缺省返回null,可以被override,线程第一次使用 get() 方法访问变量时将调用此方法,但如果线程之前调用了 set(T) 方法,则不会对该线程再调用 initialValue 方法。通常,此方法对每个线程最多调用一次,但如果在调用 get() 后又调用了 remove(),则可能再次调用此方法。
ThreadLocal的get方法:
/** * Returns the value in the current thread's copy of this * thread-local variable. If the variable has no value for the * current thread, it is first initialized to the value returned * by an invocation of the {@link #initialValue} method. * * @return the current thread's value of this thread-local */ public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) return (T)e.value; } return setInitialValue(); } * * @param t the current thread * @return the map */ ThreadLocalMap getMap(Thread t) { return t.threadLocals; }