看代码结合ThreadLocal、TransmittableThreadLocal等源码来体会,一言难尽!
package com.sankuai.meituan.kuailv.pas.service.saasfilter.intercepters;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by zhuqiuhui on 2017/12/2.
*/
public class ThreadTest {
private static class A{
private String name;
public A() {}
public A(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// ThreadLocal 测试子线程取父线程的值
private static void testThreadLocal() throws InterruptedException {
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(8);
// 子线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子线程取值为:" + threadLocal.get());
}
});
thread.start();
// 主线程休息一会,让子线程走完
Thread.sleep(1000);
System.out.println("父线程取值为:" + threadLocal.get());
}
// InheritableThreadLocal 测试子线程取父线程的值
private static void testInheritableThreadLocal() throws InterruptedException {
InheritableThreadLocal<Integer> integerInheritableThreadLocal = new InheritableThreadLocal<>();
integerInheritableThreadLocal.set(8);
InheritableThreadLocal<A> aInheritableThreadLocal = new InheritableThreadLocal<>();
aInheritableThreadLocal.set(new A("A"));
// 子线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子线程取值为:" + integerInheritableThreadLocal.get());
integerInheritableThreadLocal.set(7);
aInheritableThreadLocal.get().setName("B");
}
});
thread.start();
// 主线程休息一会,让子线程走完
Thread.sleep(1000);
System.out.println("父线程取 Integer 值为:" + integerInheritableThreadLocal.get());
System.out.println("父线程取 A 值为:" + aInheritableThreadLocal.get().getName());
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("子线程-01:"+aInheritableThreadLocal.get().getName());
aInheritableThreadLocal.set(new A("C"));
System.out.println("子线程-02:"+aInheritableThreadLocal.get().getName());
}
};
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(runnable);
// 主线程休息一会,让子线程走完,再提交一个线程
Thread.sleep(1000);
executorService.submit(runnable);
// 主线程休息一会,让子线程走完,打印主线程
Thread.sleep(1000);
executorService.shutdown();
System.out.println(aInheritableThreadLocal.get().getName());
}
// TransmittableThreadLocal 测试子线程取父线程的值
// Git: https://github.com/alibaba/transmittable-thread-local
private static void testTransmittableThreadLocal() throws InterruptedException {
TransmittableThreadLocal<Integer> transmittableThreadLocal = new TransmittableThreadLocal<>();
transmittableThreadLocal.set(8);
TransmittableThreadLocal<A> aTransmittableThreadLocal = new TransmittableThreadLocal<>();
aTransmittableThreadLocal.set(new A("A"));
// 子线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子线程取值为:" + transmittableThreadLocal.get());
transmittableThreadLocal.set(7);
aTransmittableThreadLocal.get().setName("B");
}
});
thread.start();
// 主线程休息一会,让子线程走完
Thread.sleep(1000);
System.out.println("父线程取 Integer 值为:" + transmittableThreadLocal.get());
System.out.println("父线程取 A 值为:" + aTransmittableThreadLocal.get().getName());
// 解决线程池中子线程不是从父线程中读取值的问题(阿里开源)
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("子线程-01:"+aTransmittableThreadLocal.get().getName());
aTransmittableThreadLocal.set(new A("C"));
System.out.println("子线程-02:"+aTransmittableThreadLocal.get().getName());
}
};
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(TtlRunnable.get(runnable));
// 主线程休息一会,让子线程走完,再提交一个线程
Thread.sleep(1000);
executorService.submit(TtlRunnable.get(runnable)); // TtlRunnable
// 主线程休息一会,让子线程走完,打印主线程
Thread.sleep(1000);
executorService.shutdown();
System.out.println(aTransmittableThreadLocal.get().getName());
}
public static void main(String[] args) throws InterruptedException {
System.out.println("============ThreadLocal================");
testThreadLocal();
System.out.println("============InheritableThreadLocal================");
testInheritableThreadLocal();
System.out.println("============TransmittableThreadLocal================");
testTransmittableThreadLocal();
}
}
输出:
============ThreadLocal================
子线程取值为:null
父线程取值为:8
============InheritableThreadLocal================
子线程取值为:8
父线程取 Integer 值为:8
父线程取 A 值为:B
子线程-01:B
子线程-02:C
子线程-01:C
子线程-02:C
B
============TransmittableThreadLocal================
子线程取值为:8
父线程取 Integer 值为:8
父线程取 A 值为:B
子线程-01:B
子线程-02:C
子线程-01:B
子线程-02:C
B
Process finished with exit code 0