ThreadLocal 設(shè)計(jì)和內(nèi)存泄漏

其實(shí)我一直不太理解 threadlocal的設(shè)計(jì),以及 threadlocal 涉及到的內(nèi)存泄漏毕骡。

換個(gè)思路削饵, 如果我不用threadlocal, 我自己如何實(shí)現(xiàn) 線程私有對(duì)象未巫。

最開始窿撬,我們還是會(huì)通過(guò)Thread.currentThread() 獲取當(dāng)前線程,
然后叙凡,我給每個(gè)thread 一個(gè) set 方法劈伴, setPrivateObject(Object v)
這樣,每個(gè)線程都可以存一個(gè) privateObject握爷。

但是通常我們知道跛璧,一個(gè)線程可能創(chuàng)建多個(gè)私有對(duì)象, 那這個(gè)時(shí)候我們的方案該怎么改進(jìn)新啼?

一種粗暴的方法追城,我給每個(gè)Thread 設(shè)置一個(gè) List<Object> pObjects. 每次set 的時(shí)候我就addIntoList。
但是Get()的時(shí)候咋辦燥撞? 總不能遍歷 List座柱,然后根據(jù) Object Type 來(lái)判斷是不是我想要的對(duì)象吧?

這種方法顯然是不行的物舒,那就用map 吧色洞, map的key 是什么? key 就是 Object的類型冠胯。

Map<ClassType, Key> pmap; set(obj.class, val), get(obj.class)

這樣就可以很方便的獲得相應(yīng)的 私有對(duì)象了火诸。

但是存type還是有局限性,為啥荠察? 同一個(gè)類型的私有對(duì)象只能有一個(gè)置蜀。

那我就不要存class 類型奈搜,而是存一個(gè)包含class類型對(duì)象類型。比如我叫 PrivateLocal<T> 對(duì)象盯荤,然后作為key媚污,
這樣就解決了 同一個(gè)類型不能多個(gè)的問(wèn)題。

到這里廷雅,總的方案就是 每個(gè)Thread 里面有一個(gè)map,
這個(gè)map的類型是 Map<PrivateLocal<T>,Object> pMaps;

再去看 thread的源碼京髓,其實(shí)實(shí)現(xiàn)和上面的思路是一樣的航缀,只不過(guò) PrivateLocal 變成了 ThreadLocal<T> 對(duì)象。
并且封裝了其他的方法我們?cè)趤?lái)看堰怨。

假設(shè)使用我們的設(shè)計(jì)方案芥玉,每次 set 或者是 get 的時(shí)候,
我們需要 這樣做备图?

PrivateLoacl<T> type 1 = new PrivateLocal();
Object value = new Object()
Thread.currentThread().set(type1,value);

get 他和時(shí)候灿巧, Thread.currentThread().get(type1);

每次都需要Thread.currentThread() 來(lái)操作。
有沒(méi)有更簡(jiǎn)單的方法揽涮? 有抠藕,就是 threadLocal的現(xiàn)在的做法。

他把set 和 get 方法集成到了 ThreadLocal 里面蒋困。

也就是相當(dāng)于封裝了 一個(gè) set(value)
{
Thread.currentThread().set(this,value)
}

這樣盾似,只要用戶在使用 threadLocal對(duì)象,就不必重復(fù)使用 Thread.currentThread()雪标。
而且這種設(shè)計(jì)也更符合封裝的思想零院, ThreadLocal是一個(gè)線程私有對(duì)像, 哪個(gè)線程調(diào)用 我的set方法村刨,val就屬于哪個(gè)線程告抄,這很直接。

所以源碼設(shè)計(jì)的人還是挺大師的嵌牺。

最后來(lái)看看打洼,為啥有內(nèi)存泄漏。
Thread 對(duì)象里面有一個(gè)
Map<PrivateLocal<T>,Object> pMaps

假設(shè) 這個(gè)thread 不銷毀的話髓梅,這個(gè)pMap 就不會(huì)銷毀拟蜻, 那么 <key, value> 就不會(huì)銷毀。
但是枯饿,我們知道現(xiàn)在 http server等酝锅,很多都是線程池設(shè)計(jì), thread可能很久都不會(huì)銷毀奢方,
而threadlocal 壽命是很短的搔扁,這樣不用的對(duì)象就會(huì)存在爸舒。

怎么辦?
java里面使用了weakReference來(lái)包裝 Threalocal 作為一個(gè) key稿蹲, weakreference 保證 這個(gè)key 在 下一次垃圾回收的時(shí)候被銷毀扭勉。

那么這個(gè)entry 會(huì)變成<null, Value>,
雖然 key 被收回去了,但是entry 還是被pMaps 引用啊苛聘。 這個(gè)還是無(wú)法銷毀涂炎,這就是threadlocal的內(nèi)存泄漏。

怎么辦设哗?

java 推薦的方法就是 在使用完 threadlocal 之后唱捣, 記得調(diào)用 remove方法
而且要在 finally調(diào)用。

這個(gè)是和使用 lock 一樣的网梢。 申請(qǐng)了鎖震缭,一定要記得 release 鎖,而且是在finally 語(yǔ)句里面战虏。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拣宰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子烦感,更是在濱河造成了極大的恐慌巡社,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啸盏,死亡現(xiàn)場(chǎng)離奇詭異重贺,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)回懦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門气笙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人怯晕,你說(shuō)我怎么就攤上這事潜圃。” “怎么了舟茶?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵谭期,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我吧凉,道長(zhǎng)隧出,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任阀捅,我火速辦了婚禮胀瞪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己凄诞,他們只是感情好圆雁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著帆谍,像睡著了一般伪朽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汛蝙,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天烈涮,我揣著相機(jī)與錄音,去河邊找鬼窖剑。 笑死跃脊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的苛吱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼器瘪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼翠储!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起橡疼,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤援所,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后欣除,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體住拭,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年历帚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了滔岳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挽牢,死狀恐怖谱煤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情禽拔,我是刑警寧澤刘离,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站睹栖,受9級(jí)特大地震影響硫惕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜野来,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一恼除、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梁只,春花似錦缚柳、人聲如沸埃脏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)彩掐。三九已至,卻和暖如春灰追,著一層夾襖步出監(jiān)牢的瞬間堵幽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工弹澎, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朴下,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓苦蒿,卻偏偏與公主長(zhǎng)得像殴胧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子佩迟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容