五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(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 可以做到線程隔離?的評論 (共 條)

分享到微博請遵守國家法律
新津县| 美姑县| 新晃| 五常市| 象山县| 遂溪县| 马尔康县| 方山县| 托里县| 会泽县| 沂源县| 福安市| 大石桥市| 丰城市| 伊金霍洛旗| 定兴县| 庆城县| 忻城县| 子长县| 吉首市| 安吉县| 蒙城县| 增城市| 安达市| 麟游县| 栾川县| 北辰区| 吴桥县| 灵丘县| 黔江区| 徐水县| 鄂托克旗| 班戈县| 亳州市| 方城县| 宁武县| 佛山市| 东源县| 区。| 延寿县| 团风县|