1. 程式人生 > >在使用執行緒池等會快取執行緒的元件情況下傳遞ThreadLocal

在使用執行緒池等會快取執行緒的元件情況下傳遞ThreadLocal

最近開發的系統有一個場景在多個RPC呼叫鏈中需要傳遞一些公有引數過去。

這個時候首先想到的是ThreadLocal,但是有一個問題就是它不能在父子執行緒中傳遞上下文資訊(ThreadLocal變數資訊),這時我們考慮用InheritableThreadLocal,它可以解決父子執行緒中上下文的傳遞,但是又發現一個問題,InheritableThreadLocal線上程池複用的元件裡無法複製,最後我們這個時候考慮用TransmittableThreadLocal 解決 ,TransmittableThreadLocal這個類是來自阿里的一個開源專案:https://github.com/alibaba/tr...

。這個類就是為了解決例如使用執行緒池、Tomcat這類快取執行緒元件,如ThreadPoolExecutor、tomcat執行緒池的時候,某一執行緒中的資料和ThreadLocal等在沒有刪除或者解綁的情況下,會被下一個Runable類或者Http請求複用。而在提交任務給執行緒池時,而TransmittableThreadLocal為了解決這個問在提交任務給執行緒池時,將ThreadLocal資料一起提交,相當於重新set一次ThreadLocal。

當然光這個還不夠,我們還要把執行緒池增強或者使用TtlRunnable.get()的方式,看下面程式碼例子

package com.jd.neptune.site.util.util;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;
import com.alibaba.ttl.threadpool.TtlExecutors;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestTransmittableThreadLocal {


    private static TransmittableThreadLocal<String> ttl = new TransmittableThreadLocal<>();
    private static ThreadLocal tl = new ThreadLocal();

    private static ExecutorService executorService = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(1));
    private static ExecutorService executorService2 = Executors.newFixedThreadPool(1);

    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            ttl.set("#" + i);
            tl.set("#" + i);
//            System.out.println("main-"+ttl.get());
//            executorService.execute(() -> {
//                System.out.println("child-pool-ttl-" + ttl.get());
//                System.out.println("child-pool-tt-" + tl.get());
//            });
//            executorService2.execute(TtlRunnable.get(() -> {
//                System.out.println("child-pool2-ttl-" + ttl.get());
//                System.out.println("child-pool2-tt-" + tl.get());
//            }));
//            new Thread(() -> {
//                System.out.println("child-new-ttl-" + ttl.get());
//            }
//            ).start();
//            new Thread(() -> {
//                System.out.println("child-new-tl-" + tl.get());
//           }
//            ).start();

            executorService2.execute(() -> {
                System.out.println("child-pool2-ttl-" + ttl.get());
                System.out.println("child-pool2-tt-" + tl.get());
            });

            new Thread(() -> {
                System.out.println("child-new-ttl-" + ttl.get());
            }).start();
        }
    }
}

相關推薦

在使用執行快取執行元件情況傳遞ThreadLocal

最近開發的系統有一個場景在多個RPC呼叫鏈中需要傳遞一些公有引數過去。 這個時候首先想到的是ThreadLocal,但是有一個問題就是它不能在父子執行緒中傳遞上下文資訊(ThreadLocal變數資訊),這時我們考慮用InheritableThreadLocal,它可以解決

【搞定面試官】你還在用Executors來建立執行有什麼問題呢?

前言 上文我們介紹了JDK中的執行緒池框架Executor。我們知道,只要需要建立執行緒的情況下,即使是在單執行緒模式下,我們也要儘量使用Executor。即: ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1); //此處不該

10.執行執行的區別,執行有哪些,什麼情況使用

一:執行緒和執行緒池的區別 (1)new Thread 的弊端       a. 每次new Thread時,新建物件效能差。       b. 執行緒缺乏統一管理,可能無限制新建執行緒,相互之間競爭,可能佔用過多系統資源導致宕機或oom。       c. 缺乏更多功能

併發程式設計3:執行的使用與執行流程

併發程式設計系列的文章醞釀好久了,但由於沒有時間和毅力去寫那麼多練習 demo,很多文章寫了一半就停止了。 在寫某一系列的過程中總有其他想寫的內容蹦出來,

自定義執行、內建執行.md

自定義簡單執行緒池 python執行緒是可以重複利用的,如果呼叫的時候每次都建立一個執行緒,則太浪費資源了 我把多執行緒比作服務員,每次有客人來的時候,都分配一個專門的服務員去服務; 當客人走了之後,服務員回到空閒狀態,繼續等待新的客人 import threa

jdk執行總類以及執行的核心引數簡述

JDK自帶執行緒池總類: 1、newFixedThreadPool建立一個指定工作執行緒數量的執行緒池。每當提交一個任務就建立一個工作執行緒,如果工作執行緒數量達到執行緒池初始的最大數,則將提交的任務存入到池佇列中。 2、newCachedThreadPool建立一個可快

談談執行使用原則 (執行如何監控)

基礎知識 作為Java開發工程師,工作中基本上都會用到執行緒池。Java中執行緒池最基本的定義如下: 其中corePoolSize是執行緒池核心數目;maximumPoolSize執行緒池中執行緒的最大數目;keepAliveTime表示當執行緒數目大

Java執行中的核心執行是如何被重複利用的

在Java開發中,經常需要建立執行緒去執行一些任務,實現起來也非常方便,但如果併發的執行緒數量很多,並且每個執行緒都是執行一個時間很短的任務就結束了,這樣頻繁建立執行緒就會大大降低系統的效率,因為頻繁建立執行緒和銷燬執行緒需要時間。此時,我們很自然會想到使用執行緒池來解決這個問題。 使用執行緒池的好處

Java執行架構(二)多執行排程器

在前面介紹了java的多執行緒的基本原理資訊:《Java執行緒池架構原理和原始碼解析》,本文對這個java本身的執行緒池的排程器做一個簡單擴充套件,如果還沒讀過上一篇文章,建議讀一下,因為這是排程器的核心元件部分。 我們如果要用java預設的執行緒池來做排程器,一種選擇就是Timer和Time

執行建立和多執行等待

在部落格園看到一篇部落格 C# -- 使用執行緒池 ThreadPool 執行多執行緒任務 在這裡使用了執行緒池 雖然也實現了執行緒等待 但是執行緒等待實現的太死板  如果定義未知數量的執行緒池無法實現等待 ManualResetEvent數量已經定死 所

執行使用ExecutorService 多執行處理佇列任務

最近轉到銀行工作,在做最核心的財務賬務部分,對我來說是一個比較新的東西,工作也已經四年有餘,接觸一些新的東西,也是不錯,每天也累得像狗... 不說了。/捂臉 接下來說一種非常實用的多執行緒操作模式,此方式能夠應對大部分的多執行緒操作,稍微改一下往裡面套就可以滿足大部分的業務

Python中為什麼要使用執行?如何使用執行

  系統處理任務時,需要為每個請求建立和銷燬物件.當有大量併發任務需要處理時,再使用傳統的多執行緒就會造成大量的資源建立銷燬導致伺服器效率的下降.這時候,執行緒池就派上用場了.執行緒池技術為執行緒建立、銷燬的開銷問題和系統資源不足問題提供了很好的解決方案.   from concurren

JAVA執行--Executors之什麼是執行,為什麼使用執行以及執行的使用

1. 為什麼需要執行緒池?      多執行緒技術主要解決處理器單元內多個執行緒執行的問題,它可以顯著減少處理器單元的閒置時間,增加處理器單元的吞吐能力。              假設一個伺服器完成一項任務所需時間為:T1 建立執行緒時間,T2 線上程中執行任務的時間,T

執行的選用與執行數的指定

1、選用的兩個角度 高效能:將提交到執行緒池中的任務直接交給執行緒去處理(前提:執行緒數小於最大執行緒數),不入隊緩衝執行:希望提交到執行緒池的任務儘量被核心執行緒(corePoolSize)執行掉 2、高效能 佇列:SynchronousQueue最大執行緒數:一般設為

Java執行(2)——執行中的幾個重要方法詳解

【內容摘要】 在java中,如果需要進行多執行緒程式設計,可以採用java自帶的執行緒池來實現,執行緒池對於我們新手來說是一個非常好的選擇,因為我們可以不用關心執行緒池中執行緒是如何排程的,避免在多執行緒程式設計過程產生死鎖等問題。在瞭解執行緒池的使用前,本文

使用執行與CountDownLatch多執行提升系統性能

下面這個業務場景,大家可能都會遇到,在遍歷一個list的時候,需要對list中的每個物件,做一些複雜又耗時的操作,比如取出物件的uid,遠端呼叫一次userservice的getUserByUid方法,這屬於IO操作了,可怕的是遍歷到每個物件時,都得執行一次這種

Java併發程式設計中四種執行及自定義執行使用教程

引言 通過前面的文章,我們學習了Executor框架中的核心類ThreadPoolExecutor ,對於執行緒池的核心排程機制有了一定的瞭解,並且成功使用ThreadPoolExecutor 建立了執行緒池。 而在Java中,除了ThreadPoolExecutor ,Executor框

統計執行所有任務的執行總耗時

ExecutorService executor = Executors.newFixedThreadPool(10); long start = System.currentTimeMillis(); for (int i =

執行為什麼能維持執行不釋放,隨時執行各種任務?

執行緒池 之前一直有這個疑問:我們平時使用執行緒都是各種new Thread(),然後直接在run()方法裡面執行我們要做的各種操作,使用完後需要做什麼管理嗎?執行緒池為什麼能維持住核心執行緒不釋放,一直接收任務進行處理呢? 執行緒 執行緒無他,主要有兩個方法

執行 --------常見的四中執行

由於執行緒的頻繁排程,而影響效能,通過執行緒池來維護,減少執行緒的頻繁的建立和銷燬。 在Executors統一管理,看一下常見的四中執行緒池: 1.newFixedThreadPool:建立定長的執行緒池,超出定長線上程佇列中等待。 public static ExecutorSe