ThreadLocal独家解秘 附JDK源码

public class ThreadLocalTest {

ThreadLocal<String> tl = new ThreadLocal<String>();

ThreadLocal<String> t2 = new ThreadLocal<String>();

/**
* @author zlz
*
* @time 2013-7-11上午10:14:50
* @param args
*/
public static void main(String[] args) {

ThreadLocalTest tlt = new ThreadLocalTest();
tlt.t2.set("Main Thread 2");

tlt.tl.set("Main Thread");

Thread t = new Thread(new Runnable() {

@Override
public void run() {
ThreadLocalTest tlt = new ThreadLocalTest();
tlt.tl.set("Child Thread Local 1");
tlt.tl.set("Child Thread Local 2");
System.out.println("Child Thread ID:"
+ Thread.currentThread().getId() + "---" + tlt.tl.get());
}
});
t.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


System.out.println("Main Thread ID:" + Thread.currentThread().getId()
+ "---" + tlt.t2.get());
System.out.println("Main Thread ID:" + Thread.currentThread().getId()
+ "---" + tlt.tl.get());

}

}
  执行结果:
Child Thread ID:11---Child Thread Local 2
Main Thread ID:1---Main Thread 2
Main Thread ID:1---Main Thread

子线程的值改变后不会影响主线程
单一线程内多次赋值,则最后一次生效


结论:
ThreadLocal 结构如下
Thread类中有对象 ThreadLocal.ThreadLocalMap<ThreadLocal,Object>
ThreadLocal通过 Thread.CurrentThread获取对应的ThreadLocalMap对象
ThreadLocal本身就是一个变量,他只能有一个值。多次赋值则最后一次生效.
JDK源码:

public class ThreadLocal<T> {
...
...
...
    /**
     * 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
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            //再通过当前threadLocal对象this获取值
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }

ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }
...
}

publicclass Thread implements Runnable
{
  ThreadLocal.ThreadLocalMap threadLocals = null;
}

posted on 2013-07-18 17:01  hiaming  阅读(132)  评论(0编辑  收藏  举报

导航