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