ThreadLocal从字面意思来看是线程本地(变量),有什么作用呢?
存放在ThreadLocal中的变量值只在当前线程中可见及使用。那仅在当前线程可用,自然就不存在多线程并发冲突问题,是一种空间(每个线程单独存储变量)换时间的解决多线程并发问题的方式。
下面举例说明:
package threadLocalDemo;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo {
static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
//创建一个仅有一个线程的线程池(模拟在一个线程中的前后操作)
ExecutorService executorService = Executors.newFixedThreadPool(1);
//线程提交任务:线程中设置ThreadLocal变量并打印
executorService.submit(() -> {
threadLocal.set("hello");
System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
});
//线程延迟1s提交任务:获取ThreadLocal变量并打印
Thread.sleep(1000);
executorService.submit(() -> {
System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
});
//线程延迟1s提交任务:获取ThreadLocal变量并打印
Thread.sleep(1000);
executorService.submit(() -> {
System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
});
executorService.shutdown();
}
}
打印结果如下:
pool-1-thread-1:hello
pool-1-thread-1:hello
pool-1-thread-1:hello
说明只要在当前线程中设置ThreadLocal变量后,线程的后续操作时都可以拿到此变量。
另外:在某些场景下,我们在同一线程的前后操作中是需要修改或者清空ThreadLocal变量的,当然也有相关的API,举例如下:
package threadLocalDemo;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AnotherDemo {
static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
//创建一个仅有一个线程的线程池(模拟在一个线程中的前后操作)
ExecutorService executorService = Executors.newFixedThreadPool(1);
//线程提交任务:线程中设置ThreadLocal变量并打印
executorService.submit(() -> {
threadLocal.set("hello");
System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
});
//线程延迟1s提交任务:获取ThreadLocal变量并打印
Thread.sleep(1000);
executorService.submit(() -> {
//修改变量
threadLocal.set("world");
System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
//删除变量
threadLocal.remove();
});
//线程延迟1s提交任务:获取ThreadLocal变量并打印
Thread.sleep(1000);
executorService.submit(() -> {
System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
});
executorService.shutdown();
}
}
打印结果如下:
pool-1-thread-1:hello
pool-1-thread-1:world
pool-1-thread-1:null