何为TransmittableThreadLocal
一、示例
?線程池內的線程并沒有父子關系,所以不適合InheritableThreadLocal的使用場景
public class ThreadPoolInheritableThreadLocalDemo {// static ThreadLocal<String> threadLocal = new InheritableThreadLocal<>(); // static ExecutorService pool = Executors.newFixedThreadPool(2);static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();static ExecutorService pool = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(3));public static void main(String[] args) {for(int i=0;i<100;i++) {int j = i;pool.execute(new Thread(new Runnable() {@Overridepublic void run() {ThreadPoolInheritableThreadLocalDemo.threadLocal.set("superWorld"+j);ThreadPoolInheritableThreadLocalDemo.pool.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() +" : " +ThreadPoolInheritableThreadLocalDemo.threadLocal.get());}}); }}));}}}?
?
二、TransmittableThreadLocal實現分析
?
讀取線程間傳遞的ThreadLocal 值比較麻煩,ThreadLocal 和 InheritableThreadLocal 都沒有開放內部的 ThreadLocalMap,不能直接讀取。
所以要么自己完全實現一套 ThreadLocalMap 機制(如 Netty 的 FastThreadLocal),要么就是自己實現 ThreadLocal 的子類,在每次調用 ThreadLocal
的 set/get/remove 等接口的時候,為 Thread 記錄到底綁定了哪些需要發生線程間傳遞的 ThreadLocal 對象。
/***實際存儲值的工作還是父類ThreadLocal完成*TransmittableThreadLocal 只是記錄了哪些線程使用了TransmittableThreadLocal對象*/@Overridepublic final void set(T value) {super.set(value);if (null == value) { // may set null to remove value removeValue();} else {addValue();}}/***holder 只是為了記錄使用了哪些 TransmittableThreadLocal 對象*在構造TtlRunnable/TtlCallable 的時候, 通過holder取得對應的TransmittableThreadLocal*InheritableThreadLocal的默認值是WeakHashMap*/private static InheritableThreadLocal<Map<TransmittableThreadLocal<?>, ?>> holder =new InheritableThreadLocal<Map<TransmittableThreadLocal<?>, ?>>() {@Overrideprotected Map<TransmittableThreadLocal<?>, ?> initialValue() {return new WeakHashMap<TransmittableThreadLocal<?>, Object>();}@Overrideprotected Map<TransmittableThreadLocal<?>, ?> childValue(Map<TransmittableThreadLocal<?>, ?> parentValue) {return new WeakHashMap<TransmittableThreadLocal<?>, Object>(parentValue);}};private void addValue() {if (!holder.get().containsKey(this)) {holder.get().put(this, null); // WeakHashMap supports null value. }}private void removeValue() {holder.get().remove(this);}
?
調用ThreadPoolInheritableThreadLocalDemo.threadLocal.set("superWorld"+j)時,?
holder.get().containskey(this) 為false
?
?
2.?TtlRunnable
?構造TtlRunable時,設置線程對應的Map<TransmittableThreadLocal<?>, Object>>
private TtlRunnable(Runnable runnable, boolean releaseTtlValueReferenceAfterRun) {//this.copiedRef = new AtomicReference<Map<TransmittableThreadLocal<?>, Object>>(TransmittableThreadLocal.copy());this.runnable = runnable;this.releaseTtlValueReferenceAfterRun = releaseTtlValueReferenceAfterRun;}
?
TransmittableThreadLocal.copy static Map<TransmittableThreadLocal<?>, Object> copy() {Map<TransmittableThreadLocal<?>, Object> copy = new HashMap<TransmittableThreadLocal<?>, Object>();for (TransmittableThreadLocal<?> threadLocal : holder.get().keySet()) {copy.put(threadLocal, threadLocal.copyValue());}return copy;}?
?
3.運行時,備份和恢復Map<TransmittableThreadLocal<?>, Object>
TtlRunnable#run
@Overridepublic 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);}}?
?
?
?
參考:
transmittableThreadLocal
總結
以上是生活随笔為你收集整理的何为TransmittableThreadLocal的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么时候使用 InheritableTh
- 下一篇: TransmittableThreadL