最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java并發(fā)中的ThreadLocal使用詳解

 更新時間:2026年03月24日 15:55:54   作者:編碼忘我  
ThreadLocal 是 Java 中實現(xiàn)線程局部變量的重要工具,它能讓每個線程擁有自己獨立的變量副本,從而在多線程環(huán)境下避免共享數(shù)據(jù)的競爭問題,下面給大家介紹java并發(fā)中的ThredLocal使用詳解,感興趣的朋友跟隨小編一起看看吧

ThreadLocal 是 Java 中實現(xiàn)線程局部變量的重要工具,它能讓每個線程擁有自己獨立的變量副本,從而在多線程環(huán)境下避免共享數(shù)據(jù)的競爭問題。下面從作用、使用、實現(xiàn)原理、注意事項四個方面詳細說明。

1. 作用

  • 線程隔離:每個線程通過同一個 ThreadLocal 對象存取數(shù)據(jù)時,實際操作的是各自線程內(nèi)部的存儲空間,互不干擾。
  • 簡化并發(fā):無需加鎖就能保證線程安全,適合存儲線程上下文信息。
  • 避免參數(shù)傳遞:可以將一些公共信息(如用戶身份、事務連接、日志追蹤 ID)放入 ThreadLocal,在同一個線程的任意位置獲取,避免層層傳參。

2. 基本使用

// 創(chuàng)建 ThreadLocal 對象,可指定初始值
ThreadLocal<String> local = ThreadLocal.withInitial(() -> "default");
// 線程 A 中設置
local.set("valueA");
// 線程 B 中設置
local.set("valueB");
// 各自獲取
String a = local.get(); // 線程 A 得到 "valueA"
String b = local.get(); // 線程 B 得到 "valueB"
// 使用完后建議移除,避免內(nèi)存泄漏
local.remove();

常用方法:

  • set(T value):為當前線程設置值。
  • get():獲取當前線程的值,若未設置則返回初始值(通過 initialValue() 或 withInitial 指定)。
  • remove():移除當前線程的值,釋放資源。
  • initialValue():初始化方法(一般通過 withInitial 或重寫該方法)。

3. 典型應用場景

  • 數(shù)據(jù)庫連接 / 事務管理:每個線程持有自己的 Connection 對象,確保事務隔離。
  • 用戶會話 / 請求上下文:在 Web 應用中,將用戶信息存入 ThreadLocal,同一請求的 Service、DAO 層可直接獲取。
  • 線程安全的日期格式化SimpleDateFormat 非線程安全,每個線程使用自己的實例。
  • 日志追蹤 ID:為每個請求生成唯一 ID,存入 ThreadLocal,方便日志串聯(lián)。

4. 實現(xiàn)原理(核心)

ThreadLocal 的實現(xiàn)依賴于每個線程內(nèi)部的 ThreadLocalMap。

關鍵點

  • 每個線程對象(Thread)都有一個字段 threadLocals,類型為 ThreadLocalMap
  • ThreadLocalMap 是一個自定義的哈希表,其 Entry 的 key 是 ThreadLocal 實例的弱引用,value 是用戶存儲的值。
  • 當調(diào)用 set() 時,獲取當前線程的 ThreadLocalMap,將當前 ThreadLocal 對象作為 key,傳入值作為 value 存入。
  • 當調(diào)用 get() 時,同樣根據(jù)當前線程的 Map 和當前 ThreadLocal key 取出 value;若 Map 不存在則初始化,若 key 不存在則返回初始值。
  • 由于 key 是弱引用,當 ThreadLocal 實例不再被強引用時,在 GC 時 key 會被回收,但 value 仍被 Entry 強引用,可能造成內(nèi)存泄漏。

源碼簡覽

public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}
public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}

5. 注意事項與內(nèi)存泄漏

5.1 內(nèi)存泄漏風險

  • 原因:線程池中的線程會長期存活,如果 ThreadLocal 對象被回收(弱引用),但 Entry 中的 value 仍被線程的 ThreadLocalMap 強引用,導致 value 無法被回收,造成內(nèi)存泄漏。
  • 表現(xiàn):線程池中線程復用,長時間運行可能導致內(nèi)存占用持續(xù)增長。

5.2 解決方案

務必調(diào)用 remove() :在線程執(zhí)行完任務后,顯式調(diào)用 remove() 清除當前線程的變量。尤其在 Web 容器(如 Tomcat)中使用線程池時,必須養(yǎng)成習慣。

使用 try-finally 結構:

try {
    local.set(value);
    // 業(yè)務邏輯
} finally {
    local.remove();
}

5.3 其他注意事項

  • 線程池環(huán)境:由于線程會被復用,若未及時 remove(),下一個任務可能讀取到舊值,導致業(yè)務錯誤。
  • 不恰當?shù)氖褂?/strong>:避免用 ThreadLocal 傳遞大對象,增加內(nèi)存壓力。
  • 父子線程傳遞InheritableThreadLocal 可以實現(xiàn)子線程繼承父線程的值,但需謹慎使用。

6. 總結

  • ThreadLocal 提供了線程隔離的變量副本,簡化并發(fā)編程。
  • 底層通過 ThreadLocalMap 實現(xiàn),key 為弱引用,value 為強引用。
  • 使用后必須 remove() ,尤其是在線程池環(huán)境中,以防止內(nèi)存泄漏和臟數(shù)據(jù)問題。
  • 適用于存儲線程上下文、連接對象、非線程安全工具類的實例等。

到此這篇關于Java并發(fā)中的ThredLocal使用詳解的文章就介紹到這了,更多相關java并發(fā)thredlocal內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Spring security實現(xiàn)記住我下次自動登錄功能過程詳解

    Spring security實現(xiàn)記住我下次自動登錄功能過程詳解

    這篇文章主要介紹了Spring security實現(xiàn)記住我下次自動登錄功能過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • 如何使用IntelliJ?IDEA進行Java內(nèi)存分析詳解

    如何使用IntelliJ?IDEA進行Java內(nèi)存分析詳解

    這篇文章主要介紹了如何使用IntelliJ?IDEA進行Java內(nèi)存分析的相關資料,包括內(nèi)存消耗情況的查看、內(nèi)存泄漏的分析、垃圾回收情況的優(yōu)化等,通過IntelliJIDEA提供的工具,開發(fā)者可以有效地提升應用程序的性能和穩(wěn)定性,需要的朋友可以參考下
    2025-05-05
  • Spring Boot結成MyBatis-Plus最全配置指南

    Spring Boot結成MyBatis-Plus最全配置指南

    本文主要介紹了Spring Boot結成MyBatis-Plus最全配置指南,包括依賴引入、配置數(shù)據(jù)源、Mapper 掃描、基本CRUD操作等,具有一定的參考價值,感興趣的可以了解一下
    2025-03-03
  • Java多線程開發(fā)工具之CompletableFuture的應用詳解

    Java多線程開發(fā)工具之CompletableFuture的應用詳解

    做Java編程,難免會遇到多線程的開發(fā),但是JDK8這個CompletableFuture類很多開發(fā)者目前還沒聽說過,但是這個類實在是太好用了,本文就來聊聊它的應用吧
    2023-03-03
  • SpringBoot?Redis清除所有的key的實現(xiàn)方法

    SpringBoot?Redis清除所有的key的實現(xiàn)方法

    本文主要介紹了SpringBoot?Redis清除所有的key的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05
  • 簡單了解java中靜態(tài)初始化塊的執(zhí)行順序

    簡單了解java中靜態(tài)初始化塊的執(zhí)行順序

    這篇文章主要介紹了簡單了解java中靜態(tài)初始化塊的執(zhí)行順序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • idea進程結束但是項目頁面正常運行怎么辦

    idea進程結束但是項目頁面正常運行怎么辦

    這篇文章主要介紹了idea進程結束但是項目頁面正常運行怎么辦,很多朋友遇到這樣的情況不知道該如何解決了,下面小編給大家?guī)砹薸dea進程結束但是項目頁面正常運行的解決方法,需要的朋友可以參考下
    2023-03-03
  • Mybatis調(diào)用存儲過程的案例

    Mybatis調(diào)用存儲過程的案例

    這篇文章主要介紹了Mybatis如何調(diào)用存儲過程,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • 基于JavaMail的Java實現(xiàn)復雜郵件發(fā)送功能

    基于JavaMail的Java實現(xiàn)復雜郵件發(fā)送功能

    這篇文章主要為大家詳細介紹了基于JavaMail的Java實現(xiàn)復雜郵件發(fā)送功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • MybatisPlus多條件?or()的使用問題小結

    MybatisPlus多條件?or()的使用問題小結

    這篇文章主要介紹了MybatisPlus多條件?or()的使用問題小結,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-05-05

最新評論

泾阳县| 措勤县| 宁陕县| 元阳县| 电白县| 高淳县| 宁陵县| 邯郸市| 普兰县| 墨竹工卡县| 衢州市| 襄垣县| 阿克苏市| 高唐县| 海城市| 盐池县| 理塘县| 准格尔旗| 文化| 石景山区| 衡山县| 盈江县| 九寨沟县| 启东市| 绥棱县| 崇信县| 桂平市| 合山市| 治县。| 和林格尔县| 深泽县| 通城县| 湟源县| 临江市| 铜川市| 平定县| 依兰县| 马尔康县| 嘉定区| 达尔| 台东县|