ThreadLocal、InheritableThreadLocal 和 TransmittableThreadLocal

ThreadLocalInheritableThreadLocalTransmittableThreadLocal 是 Java 中用于线程局部变量的不同实现,适用于不同的场景。

1. ThreadLocal

ThreadLocal 提供了每个线程自己的变量副本。每个线程可以独立修改其副本,而不会影响其他线程的副本。这对于需要线程隔离的数据(例如用户会话信息)非常有用。

使用场景
  • 每个线程都有独立的数据副本,并且数据在整个线程生命周期内都不会相互干扰。
  • 比如数据库连接、用户会话信息、事务管理等。
示例代码
java 复制代码
public class ThreadLocalExample {
    private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 1);

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            threadLocal.set(2);
            System.out.println(Thread.currentThread().getName() + " " + threadLocal.get());
        });
        
        Thread thread2 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " " + threadLocal.get());
        });
        
        thread1.start();
        thread2.start();
    }
}

2. InheritableThreadLocal

InheritableThreadLocalThreadLocal 的子类,允许子线程从父线程继承值。这对于需要将上下文信息从父线程传递给子线程的情况非常有用。

使用场景
  • 当一个新线程被创建时,需要从父线程继承某些上下文数据。
  • 比如,父线程中的安全上下文、用户信息需要传递给子线程。
示例代码
java 复制代码
public class InheritableThreadLocalExample {
    private static InheritableThreadLocal<Integer> inheritableThreadLocal = new InheritableThreadLocal<>();

    public static void main(String[] args) {
        inheritableThreadLocal.set(3);

        Thread thread1 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " " + inheritableThreadLocal.get());
        });
        
        inheritableThreadLocal.set(5);

        Thread thread2 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " " + inheritableThreadLocal.get());
        });
        
        thread1.start();
        thread2.start();
    }
}

3. TransmittableThreadLocal

TransmittableThreadLocalThreadLocalInheritableThreadLocal 的增强版,主要解决了使用线程池等并发框架时,父线程中的上下文信息无法传递到子线程的问题。由阿里巴巴的开源库 TransmittableThreadLocal (TTL) 提供。

使用场景
  • 需要在线程池等场景中传递父线程的上下文数据,确保线程池复用线程时上下文信息的一致性。
示例代码
java 复制代码
import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;

public class TransmittableThreadLocalExample {
    private static TransmittableThreadLocal<Integer> transmittableThreadLocal = new TransmittableThreadLocal<>();

    public static void main(String[] args) {
        transmittableThreadLocal.set(6);

        Runnable task = TtlRunnable.get(() -> {
            System.out.println(Thread.currentThread().getName() + " " + transmittableThreadLocal.get());
        });

        Thread thread = new Thread(task);
        thread.start();
    }
}

总结

  • ThreadLocal:适用于每个线程需要独立变量副本的场景。
  • InheritableThreadLocal:适用于子线程需要继承父线程变量的场景。
  • TransmittableThreadLocal:适用于需要在线程池等并发环境中传递上下文数据的场景。

选择合适的工具取决于具体的使用需求和场景。

相关推荐
寻星探路3 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
曹牧6 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
爬山算法7 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty7257 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎7 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄7 小时前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea
忆~遂愿7 小时前
ops-cv 算子库深度解析:面向视觉任务的硬件优化与数据布局(NCHW/NHWC)策略
java·大数据·linux·人工智能
小韩学长yyds7 小时前
Java序列化避坑指南:明确这4种场景,再也不盲目实现Serializable
java·序列化
仟濹7 小时前
【Java基础】多态 | 打卡day2
java·开发语言