日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

TransmittableThreadLocal

發布時間:2024/1/17 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TransmittableThreadLocal 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、簡介

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

2、使用場景

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

  • 分布式跟蹤系統
  • 應用容器或上層框架跨應用代碼給下層SDK傳遞信息
  • 日志收集記錄系統上下文
  • 3、源碼分析

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

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

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

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

    個人認為 holder 變量的設計,極大體現了作者的智慧,讓人無數次獻上膝蓋。。。

    // 調用 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.} } // 調用 set() 方法時,同時處理 holder 中 this 指針 public final void set(T value) {super.set(value);if (null == value) { // may set null to remove valueremoveValue();} else {addValue();} } void removeValue() {holder.get().remove(this); }

    4、工作流程簡介

    自定義 TtlRunnable 實現 Runnable,TtlRunnable初始化方法中保持當前線程中已有的TransmittableThreadLocal

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

    線程池中線程 調用run方法,執行前先backup holder中所有的TransmittableThreadLocal, copiedRef中不存在,holder存在的,說明是后來加進去的,remove掉holder中的;將copied中的TransmittableThreadLocal set到當前線程中

    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);} }

    執行后再恢復 backup 的數據到 holder 中(backup中不存在,holder中存在的TransmittableThreadLocal,從holder中remove掉),將 backup 中的 TransmittableThreadLocal set到當前線程中

    5、參考文獻

  • transmittable-thread-local

  • ?

    總結

    以上是生活随笔為你收集整理的TransmittableThreadLocal的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。