成人免费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

面試官數據公司

2024-06-13 08:01:19

2021-11-08 09:18:01

CAS面試場景

2025-03-10 11:40:00

前端開發HTML

2025-03-10 00:00:00

property?attributeHTML

2024-11-19 15:13:02

2025-04-08 00:00:00

@AsyncSpring異步

2023-12-27 18:16:39

MVCC隔離級別幻讀
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一区二区在线观看 | 影视先锋av资源噜噜 | 欧美一区二区三区视频 | 国产一区二区 | 国产丝袜一区二区三区免费视频 | 全免费a级毛片免费看视频免费下 | 国产精品久久久久久久久久 | 成人亚洲片 | 久久久99国产精品免费 | av中文字幕在线 | 美女艹b | 欧美日韩视频 | 国产成人在线播放 | 99色视频| 不卡在线视频 | 亚洲视频在线一区 | 五月综合激情婷婷 | 国产999精品久久久 精品三级在线观看 | 中文字幕在线观看av | 久久出精品 | 精品一区二区在线观看 | 91一区二区三区在线观看 | 日本视频免费 | 亚洲www| 一级黄色片网址 | 日韩欧美一区二区三区 | 在线观看www| 免费黄色在线观看 | 久国产视频| 中文字幕在线免费观看 | 免费看黄色国产 | 午夜精品在线观看 | 欧美视频成人 | 国产综合精品一区二区三区 | 欧美国产视频 | 午夜爽爽爽男女免费观看影院 | 久热国产在线 | 日韩二 | 国产一级电影网 | 亚洲永久精品国产 | 免费一级做a爰片久久毛片潮喷 |