AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

基于TTL 解決線程池中 ThreadLocal 線程無法共享的問題

來源: 責編: 時間:2024-04-08 17:19:23 214觀看
導讀在Java的并發編程領域中,ThreadLocal被廣泛運用來解決線程安全困境,它巧妙地為每個線程提供獨立的變量副本,有效規避了線程間數據共享的問題。不過,在使用線程池時,傳遞線程局部變量在父子線程之間并非易事。這是因為Threa

在Java的并發編程領域中,ThreadLocal被廣泛運用來解決線程安全困境,它巧妙地為每個線程提供獨立的變量副本,有效規避了線程間數據共享的問題。HTF28資訊網——每日最新資訊28at.com

不過,在使用線程池時,傳遞線程局部變量在父子線程之間并非易事。這是因為ThreadLocal的設計初衷僅在于線程內的數據隔離,無法支持跨線程間的數據傳遞。HTF28資訊網——每日最新資訊28at.com

背景

在基于Java的應用開發領域,尤其是在利用Spring框架、異步處理和微服務架構構建系統時,常常需要在不同線程或服務之間傳遞用戶會話、數據庫事務或其他上下文信息。HTF28資訊網——每日最新資訊28at.com

舉例來說,在處理用戶請求的Web服務中,記錄日志是必不可少的一環。這些日志需包含請求的獨特標識(如請求ID),這個ID在請求進入服務時生成,并會貫穿整個處理流程,包括可能并發執行的多個子任務或被分配到線程池中不同線程上執行。(在分布式場景中通常會稱之為traceId)HTF28資訊網——每日最新資訊28at.com

在這種情況下,使用ThreadLocal來存儲請求ID會帶來問題:并發執行的子任務無法訪問父線程ThreadLocal中存儲的請求ID,而且在使用線程池時,線程的重用可能導致請求ID被錯誤地共享或丟失。HTF28資訊網——每日最新資訊28at.com

偽代碼:HTF28資訊網——每日最新資訊28at.com

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadLocalExample {        private static ThreadLocal<String> requestId = new ThreadLocal<>();    public static void main(String[] args) {        requestId.set("12345"); // 設置請求ID        ExecutorService executor = Executors.newFixedThreadPool(2);        executor.submit(() -> {            System.out.println("Child task running in a separate thread: " + requestId.get());        });        executor.shutdown();    }}

在這個示例中,父線程設置了請求ID為"12345",但是當子任務在另一個線程中執行時,無法訪問到父線程中的ThreadLocal變量requestId,因此子任務無法獲取到請求ID,可能會輸出null或者""。HTF28資訊網——每日最新資訊28at.com

偽代碼:HTF28資訊網——每日最新資訊28at.com

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadLocalThreadPoolExample {        private static ThreadLocal<String> requestId = new ThreadLocal<>();    public static void main(String[] args) {        requestId.set("12345"); // 設置請求ID        ExecutorService executor = Executors.newFixedThreadPool(2);        executor.submit(() -> {            System.out.println("Child task running in a thread pool: " + requestId.get());        });        // 另一個任務復用線程        executor.submit(() -> {            System.out.println("Another child task running in the same thread: " + requestId.get());        });        executor.shutdown();    }}

在這個示例中,如果線程池中的兩個任務在同一個線程中執行,且沒有正確處理ThreadLocal變量,可能會導致第二個任務獲取到了第一個任務的請求ID,導致請求ID的錯誤共享。HTF28資訊網——每日最新資訊28at.com

技術選型

為了應對這一難題,可以采用TransmittableThreadLocal(TTL)這一阿里巴巴開源工具庫,專為解決在使用線程池等會重用線程的情況下,ThreadLocal無法正確管理線程上下文的問題而設計。HTF28資訊網——每日最新資訊28at.com

GitHub開源地址:https://github.com/alibaba/transmittable-thread-localHTF28資訊網——每日最新資訊28at.com

TransmittableThreadLocal基于ThreadLocal進行擴展,提供了跨線程傳遞數據的能力,確保父線程傳遞值給子線程,并支持線程池等場景下的線程數據隔離。HTF28資訊網——每日最新資訊28at.com

此外,還有JDK自帶的InheritableThreadLocal,用于主子線程間參數傳遞。然而,這種方式存在一個限制:必須在主線程手動創建子線程才可使用,而在線程池中則難以實現此種傳遞機制。HTF28資訊網——每日最新資訊28at.com

具體實現

依賴引入

首先,需在項目中引入TransmittableThreadLocal的依賴。若為Maven項目,可添加以下依賴:HTF28資訊網——每日最新資訊28at.com

<dependency>  <groupId>com.alibaba</groupId>  <artifactId>transmittable-thread-local</artifactId>  <version><!-- 使用最新版本 --></version> </dependency>

使用TransmittableThreadLocal存儲請求ID

public class RequestContext {    // 使用TransmittableThreadLocal來存儲請求ID    private static final ThreadLocal<String> requestIdTL = new TransmittableThreadLocal<>();    public static void setRequestId(String requestId) {        requestIdTL.set(requestId);    }    public static String getRequestId() {        return requestIdTL.get();    }    public static void clear() {        requestIdTL.remove();    }}
創建一個線程池,并使用TTL提供的工具類確保線程池兼容TransmittableThreadLocal
import com.alibaba.ttl.threadpool.TtlExecutors;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadPoolUtil {    private static final ExecutorService pool = Executors.newFixedThreadPool(10);    // 使用TtlExecutors工具類包裝原始的線程池,使其兼容TransmittableThreadLocal    public static final ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(pool);    public static ExecutorService getExecutorService() {        return ttlExecutorService;    }}

TtlExecutors是TransmittableThreadLocal(TTL)庫中的一款實用工具類,其機制在于對Java標準庫中的ExecutorService、ScheduledExecutorService等線程池接口的實例進行包裝。HTF28資訊網——每日最新資訊28at.com

通過這種封裝,確保在使用線程池時,能夠正確地傳遞TransmittableThreadLocal中存儲的上下文數據,即使任務在不同線程中執行。這對于解決在使用線程池時ThreadLocal變量值傳遞的問題至關重要。HTF28資訊網——每日最新資訊28at.com

執行并行任務,并在任務中使用RequestContext來訪問請求ID
import java.util.stream.IntStream;public class Application {    public static void main(String[] args) {        // 模擬Web應用中為每個請求設置唯一的請求ID        String requestId = "REQ-" + System.nanoTime();        RequestContext.setRequestId(requestId);        try {            ExecutorService executorService = ThreadPoolUtil.getExecutorService();            IntStream.range(0, 5).forEach(i ->                 executorService.submit(() -> {                    // 在子線程中獲取并打印請求ID                    System.out.println("Task " + i + " running in thread " + Thread.currentThread().getName() + " with Request ID: " + RequestContext.getRequestId());                })            );        } finally {            // 清理資源            RequestContext.clear();            ThreadPoolUtil.getExecutorService().shutdown();        }    }}


HTF28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-82037-0.html基于TTL 解決線程池中 ThreadLocal 線程無法共享的問題

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 超越GPT4的Agent,我用代碼實現了!

下一篇: Go 哪里沒有做好?Rob Pike 深刻反思了

標簽:
  • 熱門焦點
  • K60至尊版剛預熱 一加Ace2 Pro正面硬剛

    Redmi這邊剛如火如荼的宣傳了K60 Ultra的各種技術和硬件配置,作為競品的一加也坐不住了。一加中國區總裁李杰發布了兩條微博,表示在自家的一加Ace2上早就已經采用了和PixelWo
  • 微信語音大揭秘:為什么禁止轉發?

    大家好,我是你們的小米。今天,我要和大家聊一個有趣的話題:為什么微信語音不可以轉發?這是一個我們經常在日常使用中遇到的問題,也是一個讓很多人好奇的問題。讓我們一起來揭開這
  • 電視息屏休眠仍有網絡上傳 愛奇藝被質疑“薅消費者羊毛”

    記者丨寧曉敏 見習生丨汗青出品丨鰲頭財經(theSankei) 前不久,愛奇藝發布了一份亮眼的一季報,不僅營收和會員營收創造歷史最佳表現,其運營利潤也連續6個月實現增長。自去年年初
  • 中國家電海外掘金正當時|出海專題

    作者|吳南南編輯|胡展嘉運營|陳佳慧出品|零態LT(ID:LingTai_LT)2023年,出海市場戰況空前,中國創業者在海外紛紛摩拳擦掌,以期能夠把中國的商業模式、創業理念、戰略打法輸出海外,他們依
  • 2納米決戰2025

    集微網報道 從三強爭霸到四雄逐鹿,2nm的廝殺聲已然隱約傳來。無論是老牌勁旅臺積電、三星,還是誓言重回先進制程領先地位的英特爾,甚至初成立不久的新
  • 2299元起!iQOO Pad明晚首銷:性能最強天璣平板

    5月23日,iQOO如期舉行了新品發布會,除了首發安卓最強旗艦處理器的iQOO Neo8系列新機外,還在發布會上推出了旗下首款平板電腦——iQOO Pad,其最大的賣點
  • 引領旗艦級影像能力向中端機普及 OPPO K11 系列發布 1799 元起

    7月25日,OPPO正式發布K系列新品—— OPPO K11 。此次 K11 在中端手機市場長期被忽視的影像板塊發力,突破性地搭載索尼 IMX890 旗艦大底主攝,支持 OIS
  • DRAM存儲器10月價格下跌,NAND閃存本月價格與上月持平

    10月30日,據韓國媒體消息,自今年年初以來一直在上漲的 DRAM 存儲器的交易價格僅在本月就下跌了近 10%,此次是全年首次降價,而NAND 閃存本月價格與上月持平。市
  • 中關村論壇11月25日開幕,15位諾獎級大咖將發表演講

    11月18日,記者從2022中關村論壇新聞發布會上獲悉,中關村論壇將于11月25至30日在京舉行。本屆中關村論壇由科學技術部、國家發展改革委、工業和信息化部、國務
Top