最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

為什么 ThreadLocal 可以做到線程隔離?

2022-07-25 21:37 作者:劉水鏡  | 我要投稿

對于 ThreadLocal 我們都不陌生,它的作用如同它的名字——用于存放「線程本地」變量。

先通過一個小例子感受一下:


運行結(jié)果:


OK,從效果上看,ThreadLocal 確實是線程隔離的,那么,它是如何做到線程隔離的呢?下面我們扒一扒源碼,看看它是如何做到的:

set() 方法的邏輯如下:

  1. 獲取當前線程

  2. 根據(jù)當前線程獲取一個 ThreadLocalMap 對象

  3. 如果 map 不為 null 則保存

  4. 如果 map 為 null 則創(chuàng)建一個 map


getMap() 和 createMap() 方法都干了啥呢?我們點進去看:

進入到兩個方法內(nèi)部后發(fā)現(xiàn),不管執(zhí)行哪個分支,最終是把值保存到了當前線程的 threadLocals 屬性中。


查看 Thread 類的源碼,你會發(fā)現(xiàn)類中定義了一個 threadLocals 屬性,且初始值為 null,其類型為 ThreadLocal.ThreadLocalMap。

到此,我們發(fā)現(xiàn)了,原來 ThreadLocal 就是把我們要傳遞的對象放到了當前線程的 threadLocals 屬性中。也就是說每個線程在用 ThreadLocal 保存對象時,其實就是將對象放到了當前線程實例對象的 threadLocals 屬性里面。這樣一來線程之間自然就是互相獨立的啦。


再看看 get() 方法:


ThreadLocal 的 get() 方法其實和 set() 方法邏輯很相似,先從當前線程的 threadLocals 屬性中取,如果該屬性為 null,那么就初始化。


當線程結(jié)束時,會調(diào)用當前線程實例的 exit() 方法,將 threadLocals 設(shè)置為 null,以便垃圾回收器將其回收掉。


最后,有一點需要格外注意:用完 ThreadLocal 一定要記得手動調(diào)用 remove() 方法,否則可能會產(chǎn)生臟數(shù)據(jù)甚至產(chǎn)生內(nèi)存泄漏。

為啥呢?上面不是說線程結(jié)束時,會將 threadLocals 置為 null 嗎?

是的,線程結(jié)束時,確實會做清理工作。

但,如果線程一直不結(jié)束呢?如果線程會被復用呢?比如使用了線程池。

所以,使用 ThreadLocal 一定要手動 remove()。


更多獨家精彩內(nèi)容盡在我的新書《Spring Boot趣味實戰(zhàn)課》中。?

為什么 ThreadLocal 可以做到線程隔離?的評論 (共 條)

分享到微博請遵守國家法律
保山市| 泾川县| 克什克腾旗| 龙门县| 湘潭市| 南郑县| 新巴尔虎左旗| 绥化市| 乐昌市| 中方县| 阿克陶县| 长岛县| 太湖县| 庆云县| 靖西县| 台东市| 藁城市| 巴青县| 怀柔区| 旌德县| 达拉特旗| 沙湾县| 西丰县| 惠东县| 油尖旺区| 麦盖提县| 辽宁省| 建阳市| 根河市| 淅川县| 鹤岗市| 巴中市| 治县。| 新蔡县| 阿图什市| 英吉沙县| 南通市| 张掖市| 赤城县| 藁城市| 绥江县|