久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

TransmittableThreadLocal詳解

 hmtomyang 2019-09-16

1,、簡介

TransmittableThreadLocal 是Alibaba開源的、用于解決 “在使用線程池等會緩存線程的組件情況下傳遞ThreadLocal” 問題的 InheritableThreadLocal 擴(kuò)展,。若希望 TransmittableThreadLocal 在線程池與主線程間傳遞,,需配合 TtlRunnableTtlCallable 使用。

2,、使用場景

下面是幾個典型場景例子,。

  1. 分布式跟蹤系統(tǒng)
  2. 應(yīng)用容器或上層框架跨應(yīng)用代碼給下層SDK傳遞信息
  3. 日志收集記錄系統(tǒng)上下文

3、源碼分析

TransmittableThreadLocal 繼承自 InheritableThreadLocal,,這樣可以在不破壞ThreadLocal 本身的情況下,,使得當(dāng)用戶利用 new Thread() 創(chuàng)建線程時仍然可以達(dá)到傳遞InheritableThreadLocal 的目的。

public class TransmittableThreadLocal<T> extends InheritableThreadLocal<T> { ...... }

TransmittableThreadLocal 相比較 InheritableThreadLocal 很關(guān)鍵的一點(diǎn)改進(jìn)是引入holder變量,,這樣就不必對外暴露Thread中的 inheritableThreadLocals(參考InheritableThreadLocal詳解),,保持ThreadLocal.ThreadLocalMap的封裝性。

// 理解holder,,需注意如下幾點(diǎn):
// 1,、holder 是 InheritableThreadLocal 變量;
// 2,、holder 是 static 變量,;
// 3、value 是 WeakHashMap,;
// 4,、深刻理解 ThreadLocal 工作原理;
private static InheritableThreadLocal<Map<TransmittableThreadLocal<?>, ?>> holder =
      new InheritableThreadLocal<Map<TransmittableThreadLocal<?>, ?>>() {
          @Override
          protected Map<TransmittableThreadLocal<?>, ?> initialValue() {
              return new WeakHashMap<>();
          }

          @Override
          protected Map<TransmittableThreadLocal<?>, ?> childValue(Map<TransmittableThreadLocal<?>, ?> parentValue) {
              return new WeakHashMap<>(parentValue);
          }
      };

個人認(rèn)為 holder 變量的設(shè)計(jì),,極大體現(xiàn)了作者的智慧,,讓人無數(shù)次獻(xiàn)上膝蓋。,。,。

// 調(diào)用 get() 方法時,同時將 this 指針放入 holder
public final T get() {
    T value = super.get();
    if (null != value) {
        addValue();
    }
    return value;
}
void addValue() {
    if (!holder.get().containsKey(this)) {
        holder.get().put(this, null); // WeakHashMap supports null value.
    }
}
// 調(diào)用 set() 方法時,,同時處理 holder 中 this 指針
public final void set(T value) {
    super.set(value);
    if (null == value) { // may set null to remove value
        removeValue();
    } else {
        addValue();
    }
}
void removeValue() {
    holder.get().remove(this);
}

4,、工作流程簡介

自定義 TtlRunnable 實(shí)現(xiàn) Runnable,TtlRunnable初始化方法中保持當(dāng)前線程中已有的TransmittableThreadLocal

private TtlRunnable(Runnable runnable, boolean releaseTtlValueReferenceAfterRun) {
    this.copiedRef = new AtomicReference<Map<TransmittableThreadLocal<?>, Object>>(TransmittableThreadLocal.copy());
    this.runnable = runnable;
    this.releaseTtlValueReferenceAfterRun = releaseTtlValueReferenceAfterRun;
}

線程池中線程 調(diào)用run方法,,執(zhí)行前先backup holder中所有的TransmittableThreadLocal,, copiedRef中不存在,holder存在的,,說明是后來加進(jìn)去的,,remove掉holder中的,;將copied中的TransmittableThreadLocal set到當(dāng)前線程中

public void run() {
    Map<TransmittableThreadLocal<?>, Object> copied = copiedRef.get();
    if (copied == null || releaseTtlValueReferenceAfterRun && !copiedRef.compareAndSet(copied, null)) {
        throw new IllegalStateException("TTL value reference is released after run!");
    }

    Map<TransmittableThreadLocal<?>, Object> backup = TransmittableThreadLocal.backupAndSetToCopied(copied);
    try {
        runnable.run();
    } finally {
        TransmittableThreadLocal.restoreBackup(backup);
    }
}

執(zhí)行后再恢復(fù) backup 的數(shù)據(jù)到 holder 中(backup中不存在,holder中存在的TransmittableThreadLocal,,從holder中remove掉),,將 backup 中的 TransmittableThreadLocal set到當(dāng)前線程中

5、參考文獻(xiàn)

  1. transmittable-thread-local

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多