ThreadLocal
ThreadLocal线程变量是一个以ThreadLocal对象为键,任意对象为值的存储结构,这个结构被附带在线程上,一个线程可以根据一个ThreadLocal对象查询到绑定到这个线程上的一个值,该值是线程私有数据,线程之间具有隔离性。
验证隔离性
import java.util.concurrent.TimeUnit;
public class ThreadLocalTest {
public static ThreadLocal<String> threadLocal = new ThreadLocal<String>();
public static void main(String args[]) throws Exception {
Thread threadA = new Thread(new ThreadLocalRunner(), "ThreadA");
Thread threadB = new Thread(new ThreadLocalRunner(), "ThreadB");
threadA.start();
threadB.start();
}
static class ThreadLocalRunner implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
threadLocal.set(Thread.currentThread().getName() + " " + String.valueOf(i));
System.out.println(Thread.currentThread().getName() + " get value = " + threadLocal.get());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
运行结果
ThreadA get value = ThreadA 0
ThreadB get value = ThreadB 0
ThreadB get value = ThreadB 1
ThreadA get value = ThreadA 1
ThreadB get value = ThreadB 2
ThreadA get value = ThreadA 2
ThreadA get value = ThreadA 3
ThreadB get value = ThreadB 3
ThreadB get value = ThreadB 4
ThreadA get value = ThreadA 4
ThreadB get value = ThreadB 5
ThreadA get value = ThreadA 5
ThreadB get value = ThreadB 6
ThreadA get value = ThreadA 6
ThreadA get value = ThreadA 7
ThreadB get value = ThreadB 7
ThreadB get value = ThreadB 8
ThreadA get value = ThreadA 8
ThreadA get value = ThreadA 9
ThreadB get value = ThreadB 9
InheritableThreadLocal
使用InheritableThreadLocal可以在子线程中取得父线程继承下来的值。
when a child thread is created, the child receives initial values for all inheritable thread-local variables for which the parent has values
当一个子线程创建的时候,子线程接收所有父线程具有的可以继承的thread-local变量值作为初始值。
Normally the child's values will be identical to the parent's; however, the child's value can be made an arbitrary function of the parent's by overriding the childValue() method in this class.
通常,子线程的值将会跟父线程的值是相同的,但是子线程可以通过覆盖这个类的childValue()方法,将子线程的值修改成任意值。
示例代码
public class ThreadLocalTest2 {
public static InheritableThreadLocalExt inheritableThreadLocal = new InheritableThreadLocalExt();
static class InheritableThreadLocalExt extends InheritableThreadLocal<String> {
@Override
protected String childValue(String parentValue) {
return parentValue + " changed by child";
}
}
public static void main(String args[]) throws Exception {
inheritableThreadLocal.set("Thread Main");
ThreadLocalRunnerSet threadLocalRunnerSet = new ThreadLocalRunnerSet();
Thread threadA = new Thread(threadLocalRunnerSet, "ThreadA");
threadA.start();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread Main get value = " + inheritableThreadLocal.get());
}
static class ThreadLocalRunnerSet implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " get value from parent thread = "
+ inheritableThreadLocal.get());
for (int i = 0; i < 10; i++) {
inheritableThreadLocal.set(Thread.currentThread().getName() + " " + String.valueOf(i));
System.out.println(
Thread.currentThread().getName() + " get value from its own = " + inheritableThreadLocal.get());
}
}
}
}
运行结果
ThreadA get value from parent thread = Thread Main changed by child
ThreadA get value from its own = ThreadA 0
ThreadA get value from its own = ThreadA 1
ThreadA get value from its own = ThreadA 2
ThreadA get value from its own = ThreadA 3
ThreadA get value from its own = ThreadA 4
ThreadA get value from its own = ThreadA 5
ThreadA get value from its own = ThreadA 6
ThreadA get value from its own = ThreadA 7
ThreadA get value from its own = ThreadA 8
ThreadA get value from its own = ThreadA 9
Thread Main get value = Thread Main