美文网首页
JUC 之 ThreadLocal 基础

JUC 之 ThreadLocal 基础

作者: Tinyspot | 来源:发表于2023-10-22 11:36 被阅读0次

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 一般可用于获取用户登陆信息

相关文章

网友评论

      本文标题:JUC 之 ThreadLocal 基础

      本文链接:https://www.haomeiwen.com/subject/utgridtx.html