終於明白阿里百度這樣的大公司,爲什麼面試經常拿ThreadLocal考驗求職者了

點擊上面↑「愛開發」關注我們

每晚10點,捕獲技術思考和創業資源洞察

什麼是ThreadLocal

ThreadLocal是一個本地線程副本變量工具類,各個線程都擁有一份線程私有的數據,線程之間的變量互不干擾,在高併發場景下,可以實現無狀態的調用。

ThreadLocal提供了線程安全的另一種思路,我們平常說的線程安全主要是保證共享數據的併發訪問問題,通過sychronized鎖或者CAS無鎖策略來保證數據的一致性。

ThreadLocal結構圖


從上面的結構圖,我們已經窺見ThreadLocal的核心機制:

每個Thread線程內部都有一個Map。
Map裏面存儲線程本地對象(key)和線程的變量副本(value)
Thread內部的Map是由ThreadLocal維護的,由ThreadLocal負責向map獲取和設置線程的變量值。
對於不同的線程,每次獲取副本值時,別的線程並不能獲取到當前線程的副本值,形成了副本的隔離,彼此之間互不干擾。

我們來看個例子。

下面的例子有3個線程[thread#1],[thread#2],[thread#3]修改類變量initValue,當類變量是ThreadLocal的時候3個線程修改的值互不影響,打印的結果都是66

上面的例子3個線程是如果做到同時獨立修改變量的,答案就在ThreadLocal的set(),get()方法裏面.

下面我們再來看看ThreadLocal

ThreadLocal類提供如下幾個核心方法:

get()方法用於獲取當前線程的副本變量值。
set()方法用於保存當前線程的副本變量值。
initialValue()爲當前線程初始副本變量值。
remove()方法移除當前前程的副本變量值。
get()方法


獲取當前線程的ThreadLocalMap對象threadLocals
從map中獲取線程存儲的K-V Entry節點。
從Entry節點獲取存儲的Value副本值返回。
map爲空的話返回初始值null,即線程變量副本爲null,需要注意的是在使用中要判斷是否爲空指針NullPointerException。
set()方法


獲取當前線程的成員變量map
map非空,則重新將ThreadLocal和新的value副本放入到map中。
map空,則對線程的成員變量ThreadLocalMap進行初始化創建,並將ThreadLocal和value副本放入map中。

remove()方法


Thread線程內部的Map在類中描述如下:

可以看到,這個ThreadLocalMap是線程中的變量,也就是說每個線程都是相互獨立的

應用場景
類似單例類TransactionSynchronizationManager,

RequestContextHolder中就是通過ThreadLocal保存各自線程變量的副本,這樣就不需要重新創建類。

一個知識點延伸出這麼多知識點,關於弱引用、 內存優化等,不僅能考驗求職者的對該知識點的掌握程度,又能考驗求職者的知識面,難怪阿里百度這樣的大公司喜歡在面試時拿它來考驗求職者。

-END-
往期精選推薦
————————————————
版權聲明:本文爲CSDN博主「愛開發V」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/X8i0Bev/article/details/101086604

發佈了43 篇原創文章 · 獲贊 119 · 訪問量 129萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章