TransmittableThreadLocal

TransmittableThreadLocal

一、概述

1、背景

大多数系统会使用线程池技术,这已经不仅仅是InheritableThreadLocal能够解决的了。

TransmittableThreadLocal 是Alibaba开源,用于实现 在使用线程池等 会缓存线程的组件时 传递ThreadLocal

2、使用场景

下面是几个典型场景例子。

  1. 分布式跟踪系统
  2. 应用容器或上层框架跨应用代码给下层SDK传递信息
  3. 日志收集记录系统上下文

3、maven依赖

<!-- TransmittableThreadLocal -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>transmittable-thread-local</artifactId>
    <version>2.14.2</version>
</dependency>

4、生效前提

当我们使用线程池时,要使得线程池的变量传递起效果,需要:

  1. 使用TtlRunnable.get(runnable)Runnable进行包装

    使用TtlCallable.get(callable)Callable进行包装

  2. 使用TtlExecutors.getTtlExecutorExecutor进行包装

    使用TtlExecutors.getTtlExecutorServiceExecutorService进行包装

    使用TtlExecutors.getTtlScheduledExecutorServiceScheduledExecutorService进行包装

第二种方式其实就是在 executesubmit 时通过 TtlRunnableTtlCallable 对原任务进行包装

至于为什么要这样,可以在下面的源码分析中找到答案。

二、源码分析 - TransmittableThreadLocal

TransmittableThreadLocal 继承自 InheritableThreadLocal

public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> implements TtlCopier<T> {
   
   
    
}

使得当用户利用 new Thread() 创建线程时仍然可以达到传递InheritableThreadLocal 的目的。

1、构造方法

// com.alibaba.ttl.TransmittableThreadLocal

public TransmittableThreadLocal() {
   
   
    this(false);
}

public TransmittableThreadLocal(boolean disableIgnoreNullValueSemantics) {
   
   
    // 是否忽略null值set,默认false
    this.disableIgnoreNullValueSemantics = disableIgnoreNullValueSemantics;
}

2、holder

TransmittableThreadLocal 相比较 InheritableThreadLocal 很关键的一点改进是引入了holder变量

这样就不必对外暴露 Thread 中的 inheritableThreadLocals,保持 ThreadLocal.ThreadLocalMap 的封装性。

// com.alibaba.ttl.TransmittableThreadLocal

// holder其实就是InheritableThreadLocal的一个匿名内部类
private static final InheritableThreadLocal<WeakHashMap<TransmittableThreadLocal<Object>, ?>> holder =
    new InheritableThreadLocal<WeakHashMap<TransmittableThreadLocal<Object>, ?>>() {
   
   

    @Override
    protected WeakHashMap<TransmittableThreadLocal<Object>, ?> initialValue() {
   
   
        return new WeakHashMap<>();
    }

    @Override
    protected WeakHashMap<TransmittableThreadLocal<Object>, ?> childValue(
        WeakHashMap<TransmittableThreadLocal<Object>, ?> parentValue
    ) {
   
   
        return new WeakHashMap<>(parentValue);
    }
};
  • holder其实就是InheritableThreadLocal的一个匿名内部类。
  • holderfinal static 修饰。
  • holder 存储的是 WeakHashMap,key 是 TransmittableThreadLocal<Object>对象,value 是对应的值
    • WeakHashMapkeyWeakReference弱引用,方便回收

3、set 方法

// com.alibaba.ttl.TransmittableThreadLocal

// 调用 set() 方法时,同时处理 holder 中 this 指针
@Override
public final void set(T value) {
   
   
    if (!disableIgnoreNullValueSemantics && value == null) {
   
   
        // 不忽略null写入,则移除本地线程变量
        remove();
    } else {
   
   
        // 调用父类ThreadLocal的set方法
        super.set(value);
        // 添加到 holder 中
        addThisToHolder();
    }
}

private void addThisToHolder() {
   
   
    if (!holder.get().containsKey(this)) {
   
   
        // WeakHashMap supports null value.
        holder.get().put((TransmittableThreadLocal<Object>) this, null);
    }
}

4、remove 方法

// com.alibaba.ttl.TransmittableThreadLocal

// 调用 remove() 方法时,同时remove holder 中 this 指针
@Override
public final void remove() {
   
   
    // 从 holder 中移除
    removeThisFromHolder();
    // 调用父类ThreadLocal的remove方法
    super.remove();
}

private void removeThisFromHolder() {
   
   
    holder.get().remove(this);
}

5、get 方法

// com.alibaba.ttl.TransmittableThreadLocal


// 调用 get() 方法时,同时将 this 指针放入 holder
@Override
public final T get() {
   
   
    // 调用父类ThreadLocal的get方法
    T value = super.get();
    // 如果允许忽略null,或者value不为null,再次添加到holder
    if (disableIgnoreNullValueSemantics || value != null) 
        addThisToHolder();
    return value;
}

private void addThisToHolder() {
   
   
    if (!holder.get().containsKey(this)) {
   
   
        // WeakHashMap supports null value.
        holder.get().put((TransmittableThreadLocal<Object>) this, null);
    }
}

三、源码分析 - TtlExecutors

public final class TtlExecutors {
   
   

    public static Executor 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scj1022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值