1. ThreadLocal
解决线程安全常用的方式是加锁,但在并发冲突时会对性能产生一定的影响
ThreadLocal 可用来避免线程竞争,ThreadLocal为每个线程创建变量副本
1.1 基础
- 普通的静态变量是所有线程共享的,ThreadLocal 可让每个线程创建自己的本地变量
- ThreadLocal 为每一个线程都提供一个变量副本,隔离多个线程对数据的数据共享
- 注:ThreadLocal不可以使用原子类型,只能使用Object类型
2. 初始化
// 方式一:
private static ThreadLocal<String> nameThreadLocal = new ThreadLocal<>();
// 方式二:可设置初始值
private static ThreadLocal<String> nameThreadLocal2 = new ThreadLocal<String>() {
@Override
protected String initialValue() {
return Thread.currentThread().getName();
}
};
// private static ThreadLocal<String> nameThreadLocal = ThreadLocal.withInitial(() -> Thread.currentThread().getName());
3. 父子线程
3.1 ThreadLocal 不支持继承
public static ThreadLocal<String> parentThreadLocal = new ThreadLocal<>();
@Test
public void parent() {
parentThreadLocal.set("Hello");
new Thread(() -> {
log.info(parentThreadLocal.get());
}).start();
log.info(parentThreadLocal.get());
}
打印结果
11:26:54.383 [main] INFO xxx.ThreadLocalDemo - Hello
11:26:54.383 [Thread-1] INFO xxx.ThreadLocalDemo - null
子线程获取不到父线程的本地变量
3.2 可被继承的ThreadLocal - InheritableThreadLocal
变量可在父子线程间的传递
public static ThreadLocal<String> childThreadLocal = new InheritableThreadLocal<>();
@Test
public void child() {
childThreadLocal.set("Hello");
new Thread(() -> {
log.info(childThreadLocal.get());
}).start();
log.info(childThreadLocal.get());
}
打印结果
11:29:51.521 [main] INFO xxx.ThreadLocalDemo - Hello
11:29:51.521 [Thread-1] INFO xxx.ThreadLocalDemo - Hello
其他:
InheritableThreadLocal 一般可用于获取用户登陆信息
网友评论