ThreadLocal--ThreadLocal介紹

🧠 一、什么是 ThreadLocal

  • ThreadLocal 是 Java 提供的一種 線程本地變量機制

  • 每個線程都維護一份自己的副本;

  • 它不用于多個線程共享變量,而是用于每個線程獨立維護自己的變量副本

  • 常用于:用戶上下文、數據庫連接、格式化對象(如 SimpleDateFormat)、日志跟蹤等場景。


🚀 二、ThreadLocal 的基本用法

ThreadLocal<String> local = new ThreadLocal<>();
local.set("hello");      // 設置當前線程的副本
String val = local.get(); // 獲取當前線程的副本
local.remove();           // 手動刪除,防止內存泄漏

每個線程訪問的是 自己的變量副本,彼此隔離。


🧱 三、ThreadThreadLocalThreadLocalMap 三者關系圖

Thread (線程對象)└── ThreadLocalMap (每個線程獨有的 map)└── Entry[] 數組├── key:ThreadLocal 對象(弱引用)└── value:真正的變量值

? 總結對應關系:

角色說明
Thread每個線程都有一個 ThreadLocalMap
ThreadLocal作為 key 存在于 ThreadLocalMap 中,指向當前線程的副本
ThreadLocalMapThread 內部的屬性,負責存儲每個 ThreadLocal 對應的數據

🎯 四、為什么 ThreadLocalMap 的 key 是 弱引用

這個想要了解更詳細可以看博主的另一篇博客:ThreadLocal--ThreadLocal 竟可能導致內存泄漏?看看 ThreadLocalMap 的弱引用機制-CSDN博客

? Java 源碼:

static class Entry extends WeakReference<ThreadLocal<?>> {Object value;
}

? 原因:防止內存泄漏(重點)

  • 如果 ThreadLocal強引用

    • 即使我們不再使用 ThreadLocal,它依然會作為 key 強引用存在,永遠不會被 GC;

    • 而且 ThreadLocalMap 屬于 ThreadThread 不結束就不會釋放內存;

    • 久而久之,value 也無法回收,造成 內存泄漏

? 如果是 弱引用

  • 當開發者不再持有 ThreadLocal 引用時,它會被 GC 回收;

  • GC 后 ThreadLocalMap 中 key 為 null;

  • 如果調用 ThreadLocal.get() / set(),會清除掉這些 stale entry(陳舊數據);

  • ? 避免內存泄漏。


💣 五、ThreadLocal 內存泄漏陷阱

  • 問題場景:

    • 線程池中線程長時間不銷毀;

    • ThreadLocal 被 GC 回收,但 ThreadLocalMap 的 value 還存在;

    • 如果不調用 .remove(),value 永遠不會清理;

  • 解決方式:

    • ? 使用完后調用 ThreadLocal.remove() 清理;

    • ? 或者用 try-finally 包裝使用邏輯:

private static final ThreadLocal<SimpleDateFormat> formatter = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));public void parseDate(String dateStr) {try {formatter.get().parse(dateStr);} finally {formatter.remove(); // 手動清除,避免內存泄漏}
}

🧰 六、ThreadLocalMap 的實現細節

  • 本質上是一個自定義的哈希表:

    • 數組結構 + 開放尋址法(沖突后線性探測)

  • 不是 HashMap,也不是 ConcurrentHashMap

  • 數組大小默認 16,按需擴容(最多 2^30)


🛠 七、常用方法詳解

方法說明
set(T value)設置當前線程副本中的值
get()獲取當前線程副本中的值
remove()刪除當前線程副本中的值
withInitial(Supplier)構造帶默認初始值的 ThreadLocal


? 示例:使用默認初始值的 ThreadLocal

ThreadLocal<Integer> counter = ThreadLocal.withInitial(() -> 0);public void increment() {counter.set(counter.get() + 1);
}

🌟 八、InheritableThreadLocal:子線程繼承父線程值

InheritableThreadLocal<String> local = new InheritableThreadLocal<>();
local.set("父線程值");new Thread(() -> {System.out.println(local.get()); // 子線程能讀取父線程設置的值
}).start();

適合:父線程傳遞上下文,如用戶ID、請求ID 等。


🧭 九、實際應用場景

場景示例
? 用戶上下文登錄后存放用戶信息:ThreadLocal<User>
? DateFormatSimpleDateFormat 非線程安全,放入 ThreadLocal
? 數據源切換動態數據源管理,存放在 ThreadLocal
? Trace ID日志鏈路追蹤,全鏈路唯一 ID 存 ThreadLocal
? Spring事務/安全Spring 的 TransactionSynchronizationManagerSecurityContextHolder 都用到了 ThreadLocal

📌 十、總結

項目內容
本質每個線程一個變量副本
原理每個線程有一個 ThreadLocalMap
結構key 為弱引用的 ThreadLocal,value 為副本值
弱引用原因防止內存泄漏,GC 后 key=null 自動清理
使用建議用完及時調用 remove()
延伸功能InheritableThreadLocal 實現值傳遞
應用場景用戶信息、日期格式化、日志追蹤、數據庫連接等

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90843.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90843.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90843.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AWS云S3+Glue+EMRonEC2+ReadShift

Amazon S3&#xff08;Amazon Simple Storage Service&#xff09;即亞馬遜簡單存儲服務&#xff0c;是 AWS&#xff08;Amazon Web Services&#xff09;提供的一種對象存儲服務&#xff0c;在大數據領域被廣泛使用。以下是關于它的詳細介紹&#xff1a;基本概念Amazon S3 主要…

OpenLayers 綜合案例-軌跡回放

看過的知識不等于學會。唯有用心總結、系統記錄&#xff0c;并通過溫故知新反復實踐&#xff0c;才能真正掌握一二 作為一名摸爬滾打三年的前端開發&#xff0c;開源社區給了我飯碗&#xff0c;我也將所學的知識體系回饋給大家&#xff0c;助你少走彎路&#xff01; OpenLayers…

語音自動生成PPT、思維導圖、會議紀要、筆記、大綱、導讀等

一、需要用到錄音工具&#xff0c;手機端工具&#xff1a;訊飛聽見二、需要用到的工具通義&#xff1a;https://www.tongyi.com/discover上傳錄音&#xff0c;描述一下&#xff0c;讓直接給生成PPT就行&#xff0c;點生成就可以生成ppt&#xff0c;對PPT進行導出就行 三、除了生…

【MySQL】腳本化快速搭建跨平臺、可定制的MySQL數據庫

冗長的廢話就省略了&#xff0c;大家看到這篇博客&#xff0c;效果如標題所示&#xff0c;我將提供完整的腳本&#xff0c;并用 「保姆級」的詳細步驟&#xff0c;給你提供一個快速搭建跨平臺、可定制的 MySQL環境的解決方案。保證無論你是 Linux 服務器管理員、macOS 開發者&a…

MAC包頭、IP包頭 、UDP包頭中的長度含義是啥?三者之間有啥區別?

以太網幀、IP包及TCP與UDP的報文格式 下面用通俗技術的方式詳細解釋&#xff1a; 1. MAC包頭&#xff08;以太網幀頭&#xff09;中的長度 字段名稱&#xff1a;EtherType/Length位置&#xff1a;以太網幀頭的第13、14字節含義&#xff1a; 如果值小于等于1500&#xff08;0x0…

Multiscale Structure Guided Diffusion for Image Deblurring 論文閱讀

基于多尺度結構引導擴散模型的圖像去模糊 摘要 擴散概率模型&#xff08;Diffusion Probabilistic Models, DPMs&#xff09;最近被用于圖像去模糊&#xff0c;其被表述為一個以模糊輸入為條件的圖像條件生成過程&#xff0c;將高斯噪聲映射到高質量圖像。當在成對的域內數據上…

git 提交時排除一個或多個文件

前言 在提交文件時&#xff0c;總是有一些文件是不需要提交的&#xff0c;比如機器上的配置文件&#xff0c;日志文件等等&#xff0c;所以在提交時就需要排除這些文件&#xff1b; 第一種方案 git add file1 file2 比如我新添加了3個文件&#xff1a; file1.txt file2.txt fil…

OpenCV 入門:基礎圖像操作

在計算機視覺領域&#xff0c;OpenCV 無疑是最受歡迎的開源庫之一。它由 Intel 公司俄羅斯團隊發起&#xff0c;如今已成為處理圖像和視頻的強大工具。本文我會介紹OpenCV 的基礎知識&#xff0c;從圖像的讀寫顯示到實時視頻流處理&#xff0c;邁出計算機視覺的第一步。 目錄 …

大語言模型 LLM 通過 Excel 知識庫 增強日志分析,根因分析能力的技術方案(3):使用云平臺最小外部依賴方案

文章大綱 1 方案總覽(與官方文檔映射) 2 環境準備(一步完成) 3 數據層(零代碼遷移 Excel → BigQuery 或 SQLite) 4 函數聲明(JSON Schema 與官方示例一致) 5 Cloud Function(**最小外部依賴**) 6 客戶端調用(對齊官方 Python 示例) 7 Token 與性能對比(官方計費口…

C++高效實現軌跡規劃、自動泊車、RTS游戲、戰術迂回包抄、空中軌跡、手術機器人、KD樹

C++ 算法匯總 基于C++的城市道路場景 以下是基于C++的城市道路場景中車輛緊急變道軌跡生成的實現方法和示例代碼。內容涵蓋軌跡規劃算法、數學建模及代碼實現,適用于自動駕駛或駕駛輔助系統開發。 基于多項式曲線的軌跡生成 采用五次多項式(Quintic Polynomial)生成平滑…

電動汽車轉向系統及其工作原理

電動汽車的轉向系統作為電動汽車的一個關鍵系統&#xff0c;與燃油車的轉向系統有著較大差異。電動汽車的轉向系統主要分為 電動助力轉向&#xff08;EPS, Electric Power Steering&#xff09; 、電動液壓助力轉向系統&#xff08;EHPS, Electro-Hydraulic Power Steering&…

TCP/IP 體系結構網絡接口層的原理

TCP/IP 網絡接口層詳解 網絡接口層&#xff08;Network Interface Layer&#xff09;是 TCP/IP 模型的最底層&#xff08;對應 OSI 模型的物理層 數據鏈路層&#xff09;&#xff0c;負責在物理網絡中傳輸原始比特流&#xff0c;實現相鄰設備之間的可靠數據傳輸。核心功能物理…

筆記本鍵盤的啟用和禁用

管理員 打開 CMD&#xff1a;這一步要求以管理員權限打開命令提示符&#xff08;Command Prompt&#xff09;。在Windows系統中&#xff0c;可以通過搜索“cmd”&#xff0c;然后右鍵選擇“以管理員身份運行”來實現。sc config i8042prt start disabled (關閉筆記本鍵盤)&…

vue3的一些淺顯用法

1/ 父頁面調用子頁面相關需要在父頁面引用 <FieldUserForm ref"userFormRef" success"handleUserFormSuccess" />其中 FieldUserForm 是子頁面 success"handleUserFormSuccess" 是子頁面成功后回調方法 父頁面 實現 handleUserFormSucces…

C語言習題講解-第五講-循環編程練習等

C語言習題講解-第五講-循環編程練習等1. 關于一維數組描述不正確的是&#xff1a;( )2. 關于一維數組初始化&#xff0c;下面哪個定義是錯誤的&#xff1f;&#xff08; &#xff09;3. 定義了一維 int 型數組 a[10] 后&#xff0c;下面錯誤的引用是&#xff1a;&#xff08; &…

MongoDB索引及其原理

目錄 索引原理 索引類型 單鍵索引 組合索引 特性索引 唯一索引 稀疏索引 部分索引 TTL索引 多鍵索引 文本索引 地理空間索引 哈希索引 總結 MongoDB 索引執行計劃 索引原理 MongoDB索引的背后的原理和MySQL中的索引原理是差不多的,都是使用B數來對數據進行管理…

學習嵌入式的第三十三天-數據結構-(2025.7.25)服務器/多客戶端模型

服務器/多客戶端模型循環服務器 while(1){ accept(); recv(); } 適用于簡單任務&#xff0c;如基礎Web服務器&#xff0c;但無法處理并發請求。并發服務器 通過thread或fork實現多任務處理。需注意子進程/線程的資源回收&#xff0c;避免內存泄漏。多路IO模型服務器 使用select…

【Canvas與標牌】優質資產六角星標牌

【成圖】【代碼】<!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>優質資產六角星標記 Draft1</title><style type"text/cs…

掃雷游戲開發教程:從零打造精美像素掃雷

完整源碼在本文結尾處一、游戲概述 掃雷是一款經典的益智游戲&#xff0c;玩家需要在不觸發地雷的情況下揭開所有安全格子。本教程將帶你從零開始開發一個具有精美界面和動畫效果的掃雷游戲&#xff0c;包含難度選擇、棋盤大小調整等高級功能。 二、游戲核心功能 三種難度級別&…

Linux驅動開發筆記(五)——設備樹(上)

內容詳見《【正點原子】I.MX6U嵌入式Linux驅動開發指南》四十三章 開發板&#xff1a;imx6ull mini 虛擬機&#xff1a;VMware17 ubuntu&#xff1a;ubuntu20.04 一、什么是設備樹 視頻&#xff1a;第6.1講 Linux設備樹詳解-什么是設備樹&#xff1f;_嗶哩嗶哩_bilibili 對…