成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

嘮點面試官愛聽的系列之ThreadLocal

開發 前端
ThreadLocal 是 Java 中的一個類,用于創建線程局部變量。每個線程對 ThreadLocal 變量的訪問都是獨立的,每個線程都會擁有自己獨立的副本。

面試官:“看你簡歷寫了熟悉 Java 并發編程,那你給我講講 ThreadLocal 吧。”

我:“ThreadLocal 是 Java 中的一個類,用于創建線程局部變量。每個線程對 ThreadLocal 變量的訪問都是獨立的,每個線程都會擁有自己獨立的副本。”

完蛋,這么嘮,面試官一看就是背的八股,一點自己的東西都沒有。

你得嘮點面試官愛聽的,要有一定深度,讓面試官看出自己的思考。

下面我先來打個樣。

我在實際開發項目有利用過 ThreadLocal 存儲用戶信息,并對 ThreadLocal 源碼有過一定研究。

ThreadLocal 的優勢是無鎖化提升并發性能和簡化變量的傳遞邏輯,每個線程對 ThreadLocal 變量的訪問都是獨立的,每個線程都會擁有自己獨立的副本。

我:“需要我展開聊聊嗎?”

面試官:“好的。”

ThreadLocal 存儲的變量實際上是存儲在 Thread 線程對象中,在 Thread 類中有兩個 ThreadLocalMap 類型的變量一個是 threadLocals,另一個是 inheritableThreadLocals。

其中 threadLocals 就是用于存儲 ThreadLocal 對應的變量。ThreadLocalMap 也是哈希數據結構,不過與我們用的最多的 HashMap 有所不同。

ThreadLocalMap 解決哈希沖突采用的是線性探測法,而 HashMap 采用的是拉鏈法。

ThreadLocalMap 的初始容量是 16,當負載達到 2/3 的時候會觸發擴容邏輯,擴容的時候容量*2。

ThreadLocalMap 通過 Entry 數組存儲數據。每一個 Entry 對象的 key 是一個弱引用指向的 ThreadLocal 對象。值是一個強引用的對象,類型由 ThreadLocal 對象的泛型 <> 決定。

在 Entry 對象中 ThreadLocal 之所以使用弱引用進行鏈接是為了減少當內存泄露發生時所帶來的內存損失。

一旦 ThreadLocal 對象失去了外界強引用,在發生垃圾回收時僅被 Entry 對象弱引用的 ThreadLocal 對象就會被垃圾回收器回收,這時該 Entry 對象就是所謂的過時 Entry。

過時 Entry 自身及其引用的 vlaue 值在其它 ThreadLocal 對象執行 get、set、remove 方法時,可能會被清理,從而釋放泄露的內存。

當然在實際開發中,我們更應該主動在恰當時機調用 remove 方法,對不再使用的 ThreadLocal 對象進行清理,避免觸發 ThreadLocal 的清理機制,進而提升 get、set、remove 方法的執行效率。

需要注意的一點,我們通常所使用的 web 容器 tomcat 對工作線程的管理使用了池化技術,也就是說 Thread 對象會被重復使用。

如果我們在一個請求結束的時候沒有調用 remove 方法清理 ThreadLocal 對象,并且其他請求在執行 get 方法前沒有執行 set 方法進行設置值,那么可能會發生匪夷所思的業務異常。

咦?為什么當前是 A 發起的請求,獲取到的卻是 B 的信息?

圖片圖片

ThreadLocal 類有一個子類叫做 InheritableThreadLocal,InheritableThreadLocal 主要解決在單次請求過程中涉及到了多線程異步處理邏輯時,ThreadLocal 變量無法傳遞問題。

雙十一有一個比價需求,需要拉取同商品在拼多多、淘寶、京東、抖音上的價格進行比價,如果采用單線程去執行,需要依次進行調用,該接口總耗時為獲取各大平臺價格耗時的累加和。

此時要想提高接口執行效率可以采取多線程方案,但是在獲取各大平臺優惠價時需要獲取 ThreadLocal 中存儲的上下文信息。

但是,我們前面說過 ThreadLocal 儲存的上下文,其實是存儲在了 Thread 對象中。

而采取多線程方案時,獲取各大平臺價格的線程并不是之前的主線程,這時是無法直接通過 ThreadLocal 的 get 方法獲取到在主線程存儲的上下文信息。

此時怎么辦呢?有兩種方案,第一種是在開啟多線程之前先取出上下文信息,然后作為參數傳遞給每一個線程,但是這不是與 ThreadLocal 簡化變量的傳遞邏輯的初衷相悖了嗎?

通過 InheritableThreadLocal 就可以很好的解決這個問題,在線程初始化的時候,當前線程的 inheritableThreadLocals 會拷貝給新創建線程的 inheritableThreadLocals。

inheritableThreadLocals 就是上文提到的 Thread 線程對象中的另外一個 ThreadLocalMap 類型變量,用于存儲 InheritableThreadLocal 記錄的信息。

圖片圖片

我:“以上就是我對 ThreadLocal 的一些認識。”

內心甚至期盼著面試官繼續深究,看過源碼解讀系列完全不慌!

想要進行一步了解 ThreadLocal 的小伙伴可以回看 ThreadLocal 源碼解讀系列。

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2024-09-24 10:28:22

2022-10-25 10:20:31

線程變量原理

2022-11-04 08:47:52

底層算法數據

2024-03-13 07:53:57

弱引用線程工具

2021-05-31 11:43:19

B-樹MySQL索引

2021-06-02 10:23:06

索引B+樹數據

2015-08-13 10:29:12

面試面試官

2021-03-03 17:26:45

面試Synchronous底層

2020-11-30 11:01:34

反射用途實現

2022-05-23 08:43:02

BigIntJavaScript內置對象

2010-08-12 16:28:35

面試官

2023-02-16 08:10:40

死鎖線程

2018-10-22 14:28:26

面試官數據公司

2021-11-08 09:18:01

CAS面試場景

2024-06-13 08:01:19

2025-04-08 00:00:00

@AsyncSpring異步

2021-12-25 22:31:10

MarkWord面試synchronize

2025-03-10 11:40:00

前端開發HTML

2025-03-10 00:00:00

property?attributeHTML

2024-11-19 15:13:02

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品久久久久国产 | 日韩欧美三级电影在线观看 | 欧美日韩国产一区二区三区 | 色综合久 | 日韩免费视频一区二区 | 久草成人 | 日韩快播电影网 | 亚洲国产成人精品女人 | 蜜臀网 | 国产乱码精品一区二区三区av | 欧美一区二区三区四区五区无卡码 | 国产www成人 | 国产在线高清 | 一区二区高清不卡 | 久久精品日产第一区二区三区 | 国产在线中文字幕 | 日本一区二区高清视频 | 亚洲精品二区 | 日本精品在线播放 | 亚洲精品国产一区 | 国产一区二区三区四区hd | 在线观看视频一区 | 亚洲一区二区中文字幕 | a中文在线视频 | 91久久精品国产91久久 | 亚洲成人精品 | 精品一区二区久久久久久久网站 | 成人一区二区在线 | 91av国产在线视频 | 免费观看av网站 | www.99re | 久久久久网站 | 成人网在线观看 | 91免费看片| 亚洲女人天堂成人av在线 | 亚洲欧美高清 | 涩涩片影院 | 久久久久久久国产 | 欧美中文一区 | 日韩一区二区在线观看 | 精品久久精品 |