ThreadLocal
场景:它的应用就是比如当前用户特有的一些属性,不能跟其他线程,用户共用。
TransmittableThreadLocal
场景:就是父子线程或者线程池中共用变量。
class ThreadLocalTest {
public static ExecutorService TTLExecutor = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(5));
//定义另外一个线程池循环执行,模拟业务场景下多Http请求调用的情况
public static ExecutorService loopExecutor = Executors.newFixedThreadPool(5);
AtomicInteger i = new AtomicInteger(0);
//TTL的ThreadLocal
public static ThreadLocal tl = new TransmittableThreadLocal<>(); //这里采用TTL的实现
public static void main(String[] args) {
// System.out.println(Thread.currentThread().getName());
SysDeptServiceImplTest.test2();
// SysDeptServiceImplTest.test3();
// SysDeptServiceImplTest.test4();
// ExecutorService loopExecutor = Executors.newFixedThreadPool(5);
// for (int i = 0; i < 10; i++) {
// loopExecutor.execute(() -> {
// System.out.println("父线程" + Thread.currentThread().getName());
// SysDeptServiceImplTest.test5();
// });
// }
}
/**
* ThreadLocal 值共享:当前线程
*/
public static void test1() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(1));
ThreadLocal local = new ThreadLocal();
local.set(1);
System.out.println("打印1:" + local.get());
executor.execute(() -> {
System.out.println("打印2:" + local.get());
});
}
/**
* InheritableThreadLocal 值共享:当前线程和子线程,但是线程池的不行(看test2_1)
*/
public static void test2() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(1));
ThreadLocal local = new InheritableThreadLocal();
local.set(1);
System.out.println("打印1:" + local.get());
executor.execute(() -> {
local.set(2);
System.out.println("打印2:" + local.get());
});
System.out.println("打印3:" + local.get());
}
/**
* InheritableThreadLocal 值共享:当前线程和子线程,但是线程池的不行。
*/
public static void test2_1() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(1));
ThreadLocal local = new InheritableThreadLocal();
local.set(1);
executor.execute(() -> {
System.out.println("打印1:" + local.get());
});
local.set(2);
System.out.println("打印2:" + local.get());
executor.execute(() -> {
local.set(3);
System.out.println("打印3:" + local.get());
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("打印4:" + local.get());
}
/**
* TransmittableThreadLocal 值共享:当前线程,子线程,线程池
*/
public static void test3() {
AtomicInteger i = new AtomicInteger(0);
new Thread(() -> {
System.out.println(Thread.currentThread().getName());
while (true) {
if (i.get() < 10) {
tl.set(i.getAndAdd(1));
}
TTLExecutor.execute(() -> {
System.out.println(String.format("1子线程名称-%s, 变量值=%s", Thread.currentThread().getName(), tl.get()));
});
}
}).start();
}
public static void test4() {
AtomicInteger i = new AtomicInteger(0);
new Thread(() -> {
System.out.println(Thread.currentThread().getName());
while (true) {
if (i.get() < 10) {
tl.set("A");
}
TTLExecutor.execute(() -> {
System.out.println(String.format("2子线程名称-%s, 变量值=%s", Thread.currentThread().getName(), tl.get()));
});
}
}).start();
}
public static void test5() {
AtomicInteger i = new AtomicInteger(0);
new Thread(() -> {
System.out.println(Thread.currentThread().getName());
while (true) {
if (i.get() < 10) {
tl.set(i.getAndAdd(1));
TTLExecutor.execute(() -> {
System.out.println(String.format("1子线程名称-%s, 变量值=%s", Thread.currentThread().getName(), tl.get()));
});
}
}
}).start();
}
public static void test6() {
}
}