ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal的区别

ThreadLocal

在下面的案例中,local.get()取到的值是null,因为子线程获取不到主线程的值。用InheritableThreadLocal可以让子线程获取到主线程的值。

public static void main(String[] args) {
        ThreadLocal<String> local = new ThreadLocal<>();
        local.set("123");
        /**local.get()是null
         * 虽然 local 是在主线程中定义的,但它只是一个引用.
         * 当你在不同线程中调用 local.get() 或 local.set(...) 时,
         * 操作的是当前线程内部的变量副本
         */
        Thread thread = new Thread(() -> {
            String s = local.get();
            System.out.println(s);
        });
        thread.start();
    }

InheritableThreadLocal

在下面的案例中,local.get()就可以获取到主线程的值了。

public static void main(String[] args) {
        InheritableThreadLocal<String> local = new InheritableThreadLocal<>();
        local.set("123");
        /**local.get()是null
         * 虽然 local 是在主线程中定义的,但它只是一个引用.
         * 当你在不同线程中调用 local.get() 或 local.set(...) 时,
         * 操作的是当前线程内部的变量副本
         */
        Thread thread = new Thread(() -> {
            String s = local.get();
            System.out.println(s);
        });
        thread.start();
    }

缺点:

缺点 说明
不适用于线程池 父子关系不明确,值无法正确传递
内存泄漏风险 没有及时 remove 可能导致泄露
多级嵌套复杂 值层层继承,难以控制
数据不可同步 子线程修改不影响父线程

以第四个缺点举例:

public static void main(String[] args) throws InterruptedException {
        InheritableThreadLocal<String> local = new InheritableThreadLocal<>();
        local.set("123");
        /**local.get()是null
         * 虽然 local 是在主线程中定义的,但它只是一个引用.
         * 当你在不同线程中调用 local.get() 或 local.set(...) 时,
         * 操作的是当前线程内部的变量副本
         */
        Thread thread = new Thread(() -> {
            String s = local.get();
            System.out.println("子线程获取值:"+s);
            String str = "456";
            local.set(str);
            System.out.println("子线程设置了新的值:"+str);
        });
        thread.start();
        thread.join();
        System.out.println("主线程最后获取值:"+local.get());
    }

TransmittableThreadLocal

1、支持线程池传递上下文
2、支持嵌套异步传递
3、兼容性好
使用场景
1、需要在多线程环境下传递用户上下文(如 Trace ID、登录信息等)
2、使用线程池、异步任务(CompletableFuture)、RPC 调用链追踪等场景
3、分布式系统中日志链路追踪(如配合 SkyWalking、Sleuth)

posted @ 2025-07-11 08:57  Charlie-Pang  阅读(11)  评论(0)    收藏  举报