ThreadLocal使用詳解-從源碼層面分析

從demo入手看效果

代碼Demo

    static ThreadLocal tl1 = new ThreadLocal();static ThreadLocal tl2 = new ThreadLocal();static ThreadLocal tl3 = new ThreadLocal();public static void main(String[] args) {tl1.set("123");tl2.set("456");tl3.set("4586");Thread t1 = new Thread(() -> {System.out.println("t1:tl1-before:" + tl1.get());System.out.println("t1:tl2-before:" + tl2.get());System.out.println("t1:tl3-before:" + tl3.get());ThreadLocal tl4 = new ThreadLocal();tl1.set("1231");tl2.set("4561");tl3.set("12312");tl4.set("123121231212312");System.out.println("t1:tl1-" + tl1.get());System.out.println("t1:tl2-" + tl2.get());System.out.println("t1:tl3-" + tl3.get());System.out.println("t1:tl4-" + tl4.get());});t1.start();Thread.sleep(5000);System.out.println("main:tl1-" + tl1.get());System.out.println("main:tl2-" + tl2.get());System.out.println("main:tl3-" + tl3.get());

執行結果:

t1:tl1-before:null
t1:tl2-before:null
t1:tl3-before:null
t1:tl1-1231
t1:tl2-4561
t1:tl3-12312
t1:tl4-123121231212312
main:tl1-123
main:tl2-456
main:tl3-4586

結論:
根據結果可以發現 相同的ThreadLocal 在main線程和t1 線程存入不同的數據,拿到的結果不一樣,即使主線程先在ThreadLocal執行set方法,在t1線程中還是獲取為空,可以說明在T1線程內部獲取ThreadLocal是獲取不到main線程的,因此可以證明實現了線程隔離。

源碼分析

Thread:

 ThreadLocal.ThreadLocalMap threadLocals = null;

ThreadLocal類中包含一個靜態類 ThreadLocalMap,是一個定制化的哈希表,用于存儲線程的私有數據。鍵為ThreadLocal對象(弱引用),值為線程的局部變量(強引用)
在這里插入圖片描述
ThreadLocal的set方法源碼:

設置該線程局部變量的當前線程副本到指定的值。大多數子類都不需要這樣做重寫此方法,僅依賴于{@link #initialValue}方法設置線程局部變量的值。public void set(T value) {Thread t = Thread.currentThread();//ThreadLocalMap map = getMap(t);if (map != null) {map.set(this, value);} else {createMap(t, value);}}

在上面set方法里先獲取到執行該方法的線程對象,再基于此對象去獲取該線程的ThreadLocalMap 來實現線程間的隔離數據
getMap

獲取與ThreadLocal相關聯的映射
ThreadLocalMap getMap(Thread t) {return t.threadLocals;}

createMap:創建該線程的ThreadLocalMap

void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);}

new ThreadLocalMap(this, firstValue)

ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {table = new Entry[INITIAL_CAPACITY];int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);table[i] = new Entry(firstKey, firstValue);size = 1;setThreshold(INITIAL_CAPACITY);}

**set方法執行結論:**先獲取到執行該方法的線程對象,然后基于這個對象獲取ThreadLocalMap,進行實例化,賦值。賦值的key就是ThreadLocal,雖然ThreadLocal在多線程中復用,但是實際存儲數據的是ThreadLocalMap,這個ThreadLocalMap是和Thread綁定的

get方法

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();}

getMap

ThreadLocalMap getMap(Thread t) {return t.threadLocals;}

setInitialValue

private T setInitialValue() {T value = initialValue();Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {map.set(this, value);} else {createMap(t, value);}if (this instanceof TerminatingThreadLocal) {TerminatingThreadLocal.register((TerminatingThreadLocal<?>) this);}return value;}

get方法執行結論: 先拿到執行方法的當前線程 根據當前線程去獲取map,有就以ThreadLocal為key去獲取value。

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

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

相關文章

CPO:對比偏好優化—突破大型語言模型在機器翻譯中的性能邊界

溫馨提示&#xff1a; 本篇文章已同步至"AI專題精講" CPO&#xff1a;對比偏好優化—突破大型語言模型在機器翻譯中的性能邊界 摘要 中等規模的大型語言模型&#xff08;LLMs&#xff09;&#xff0c;如參數量為 7B 或 13B 的模型&#xff0c;在機器翻譯&#xff0…

執行shell 腳本 如何將日志全部輸出到文件

在執行 Shell 腳本時&#xff0c;如果需要將 所有輸出&#xff08;包括標準輸出 stdout 和錯誤輸出 stderr&#xff09; 重定向到日志文件&#xff0c;可以使用以下方法&#xff1a;方法 1&#xff1a;直接重定向&#xff08;推薦&#xff09; /appdata/mysql_backup_dump.sh &…

Postman接口測試實現UI自動化測試

Selenium底層原理 3天精通Postman接口測試&#xff0c;全套項目實戰教程&#xff01;&#xff01;運行代碼&#xff0c;啟動瀏覽器后&#xff0c;webdriver會將瀏覽器綁定到特定的端口&#xff0c;作為webdriver的remote server&#xff08;遠程服務端&#xff09;&#xff0c;…

CSS動畫與變換全解析:從原理到性能優化的深度指南

引言&#xff1a;現代Web動畫的技術革命 在當今的Web體驗中&#xff0c;流暢的動畫效果已成為用戶交互的核心要素。根據Google的研究&#xff0c;60fps的動畫可以使用戶參與度提升53%&#xff0c;而卡頓的界面會導致跳出率增加40%。本文將深入剖析CSS動畫&#xff08;animation…

NPM組件 @ivy-shared-components/iconslibrary 等竊取主機敏感信息

【高危】NPM組件 ivy-shared-components/iconslibrary 等竊取主機敏感信息 漏洞描述 當用戶安裝受影響版本的 ivy-shared-components/iconslibrary 等NPM組件包時會竊取用戶的主機名、用戶名、工作目錄、IP地址等信息并發送到攻擊者可控的服務器地址。 MPS編號MPS-zh19-e78w…

Fail2ban防止暴力破解工具使用教程

Fail2ban防止暴力破解工具使用教程場景Fail2ban安裝和配置安裝配置原理遇到的問題以及解決辦法問題1&#xff1a;設置的策略是10分鐘內ssh連接失敗2次的ip進行封禁&#xff0c;日志中實際卻出現4次連接。問題2&#xff1a;策略設置為1分鐘內失敗兩次&#xff0c;封禁ip。但通過…

亞遠景科技助力長城汽車,開啟智能研發新征程

亞遠景科技助力長城汽車&#xff0c;開啟智能研發新征程在汽車智能化飛速發展的當下&#xff0c;軟件研發管理成為車企決勝未來的關鍵。近日&#xff0c;亞遠景科技胡浩老師應邀為長城汽車開展了一場主題深刻且極具實用價值的培訓。本次培訓聚焦軟件研發管理導論 - 建立機器學習…

圖算法在前端的復雜交互

引言 圖算法是處理復雜關系和交互的強大工具&#xff0c;在前端開發中有著廣泛應用。從社交網絡的推薦系統到流程圖編輯器的路徑優化&#xff0c;再到權限依賴的拓撲排序&#xff0c;圖算法能夠高效解決數據之間的復雜關聯問題。隨著 Web 應用交互復雜度的增加&#xff0c;如實…

Prometheus Operator:Kubernetes 監控自動化實踐

在云原生時代&#xff0c;Kubernetes 已成為容器編排的事實標準。然而&#xff0c;在高度動態的 Kubernetes 環境中&#xff0c;傳統的監控工具往往難以跟上服務的快速變化。Prometheus Operator 應運而生&#xff0c;它將 Prometheus 及其生態系統與 Kubernetes 深度融合&…

一種融合人工智能與圖像處理的發票OCR技術,將人力從繁瑣的票據處理中解放

在數字化浪潮席卷全球的今天&#xff0c;發票OCR技術正悄然改變著企業財務流程的運作模式。這項融合了人工智能與圖像處理的前沿技術&#xff0c;已成為財務自動化不可或缺的核心引擎。核心技術&#xff1a;OCR驅動的智能識別引擎發票OCR技術的核心在于光學字符識別&#xff08…

時空大數據:數字時代的“時空羅盤“

引言&#xff1a;為何需要“時空大數據”&#xff1f;“大數據”早已成為熱詞&#xff0c;但“時空大數據”的提出卻暗含深刻邏輯。中國工程院王家耀院士指出&#xff0c;早期社會存在三大認知局限&#xff1a;過度關注商業大數據而忽視科學決策需求&#xff1b;忽視數據的時空…

PySide筆記之信號連接信號

PySide筆記之信號連接信號code review! 在 PySide6&#xff08;以及 Qt 的其他綁定&#xff0c;如 PyQt&#xff09;中&#xff0c;信號可以連接到信號。也就是說&#xff0c;可以把一個信號的發射&#xff0c;作為另一個信號的觸發條件。這樣做的效果是&#xff1a;當第一個信…

Linux操作系統之線程:線程概念

目錄 前言&#xff1a; 一、進程與線程 二、線程初體驗 三、分頁式存儲管理初談 總結&#xff1a; 前言&#xff1a; 大家好啊&#xff0c;今天我們就要開始翻閱我們linux操作系統的另外一座大山&#xff1a;線程了。 對于線程&#xff0c;大體結構上我們是劃分為兩部分…

windows利用wsl安裝qemu

首先需要安裝wsl,然后在swl中啟動一個子系統。這里我啟動一個ubuntu22.04。 接下來的操作全部為在子系統中的操作。 檢查虛擬化 在開始安裝之前,讓我們檢查一下你的機器是否支持虛擬化。 要做到這一點,請使用以下命令: sean@DESKTOP-PPNPJJ3:~$ LC_ALL=C lscpu | grep …

如何使用 OpenCV 打開指定攝像頭

在計算機視覺應用中&#xff0c;經常需要從特定的攝像頭設備獲取視頻流。例如&#xff0c;在多攝像頭環境中&#xff0c;當使用 OpenCV 的 cv::VideoCapture 類打開攝像頭時&#xff0c;如果不指定攝像頭的 ID&#xff0c;可能會隨機打開系統中的某個攝像頭&#xff0c;或者按照…

JAVA面試寶典 -《分布式ID生成器:Snowflake優化變種》

&#x1f680; 分布式ID生成器&#xff1a;Snowflake優化變種 一場訂單高峰&#xff0c;一次鏈路追蹤&#xff0c;一條消息投遞…你是否想過&#xff0c;它們背后都依賴著一個“低調卻關鍵”的存在——唯一ID。本文將帶你深入理解分布式ID生成器的核心原理與工程實踐&#xff0…

蘋果的機器學習框架將支持英偉達的CUDA平臺

蘋果專為Apple Silicon設計的MLX機器學習框架即將迎來CUDA后端支持&#xff0c;這意義重大。原因如下。 這項開發工作由GitHub開發者zcbenz主導&#xff08;據AppleInsider報道&#xff09;&#xff0c;他于數月前開始構建CUDA支持的原型。此后他將項目拆分為多個模塊&#xff…

golang語法-----變量、常量

變量1、聲明與初始化&#xff08;1&#xff09;標準聲明 (先聲明&#xff0c;后賦值)var age int // 聲明一個 int 類型的變量 age&#xff0c;此時 age 的值是 0 fmt.Println(age) // 輸出: 0age 30 // 給 age 賦值 fmt.Println(age) // 輸出: 30//int 的零…

Jenkins+Docker(docker-compose、Dockerfile)+Gitee實現自動化部署

項目目錄結構 project-root/ ├── pom.xml ├── docker │ ├── copy.sh │ ├── file │ │ ├── jar │ │ │ └── 存放執行copy.sh以后jar包的位置 │ │ └── Dockerfile │ └── docker-compose.yml ├── docker-only-test │ ├─…

TASK01【datawhale組隊學習】地瓜機器人具身智能概述

https://github.com/datawhalechina/ai-hardware-robotics 參考資料地址 具身智能&#xff08;Embodied AI&#xff09; 具身智能 智能的大腦 行動的身體。 比例&#xff08;Proportional&#xff09;、積分&#xff08;Integral&#xff09;、微分&#xff08;Derivative&a…