正確解讀ThreadLocal

在Android的消息機(jī)制中信认,Handler是非常重要的一部分材义,而完全要理解Handler的機(jī)制,首先應(yīng)該理解ThreadLocal,關(guān)于ThreadLocal嫁赏,見到很多地方叫做線程本地變量其掂,也有些地方叫做線程本地存儲,其實(shí)意思差不多潦蝇】畎荆可能很多人都知道ThreadLocal為變量在每個(gè)線程中都創(chuàng)建了一個(gè)副本,那么每個(gè)線程可以訪問自己內(nèi)部的副本變量攘乒,這樣的詞容易讓人產(chǎn)生誤解或者迷惑贤牛。
首先,從最新的ThreadLocal源碼看持灰,ThreadLocal并未創(chuàng)建任何本地變量盔夜,也沒有copy副本的存在负饲,是直接用的Thread對象的成員變量堤魁,因此叫做"線程變量幫助類"其實(shí)更合適,它的作用就是拿到當(dāng)前線程對象的Object[] value數(shù)組返十,然后進(jìn)行存儲和取值妥泉,因?yàn)檫@屬于每個(gè)線程的內(nèi)部變量數(shù)組,因此也不存在共享洞坑,所以也就沒有線程安全的問題盲链。
先看一個(gè)例子:

ThreadLocal例子.png

例子可以看出不同的線程得到的值是不同的,說明ThreadLocal可以使同一個(gè)變量在不同的線程里有不同的值,為什么同一個(gè)變量在不同的線程的會(huì)表現(xiàn)出不同的值呢迟杂,源碼說明一切:

先看set方法:

set(T value).png
得到當(dāng)前Thread對象的Values值.png

可以看出ThreadLocal的Values引用直接指向Thread的localValues值刽沾。看下put()方法的實(shí)現(xiàn)排拷。

put.png

很好理解侧漓,可以簡單看做用單個(gè)數(shù)組來實(shí)現(xiàn)的簡易hashmap的,hashmap的key是當(dāng)前ThreadLocal對象的hash值與當(dāng)前數(shù)組長度的求模運(yùn)算监氢,存入在數(shù)組的index位置布蔗,value就是當(dāng)前的存入值藤违,這個(gè)值總是放在index+1的位置,可以理解為index和index+1這兩個(gè)位置就是hashmap的Entry纵揍。好像在jdk1.7之前就是用hashmap來實(shí)現(xiàn)的顿乒,原理都是一樣的。這樣是Thread類更加的輕量化泽谨。

get()

通過上面的分析get函數(shù)也很好理解了璧榄。先得到當(dāng)前線程對象的Values對象,然后得到Values中的Object[] table數(shù)組吧雹,從數(shù)組中取出值犹菱。

ThreadLocal 實(shí)例通常建議是用 private static 字段,至于原因想不太清楚吮炕。但這不是絕對的腊脱,在Android的事件機(jī)制Looper中

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

這就不是一個(gè)private變量,至于靜態(tài)

public static @Nullable Looper myLooper() {    
    return sThreadLocal.get();
}

因?yàn)樾枰o態(tài)方法獲取Looper對象龙亲,所以就必須是靜態(tài)的的吧陕凹。看到一種說法是設(shè)置static 是因?yàn)門hreadLocal支持線程范圍生命周期的變量鳄炉,所以不屬于類的屬性杜耙。不知是否有些牽強(qiáng)。
關(guān)于內(nèi)存泄露的問題

/** Weak reference to this thread local instance. */
private final Reference<ThreadLocal<T>> reference = new WeakReference<ThreadLocal<T>>(this);

因?yàn)槭擒浺贸钟蟹鞫ⅲ圆粫?huì)存在內(nèi)存泄露的問題佑女。但確定不需要使用的時(shí)候最好調(diào)用remove()方法來釋放內(nèi)存。

簡單總結(jié)

判斷是否需要對資源進(jìn)行同步的判斷準(zhǔn)則是谈竿,當(dāng)前獲取(get)資源是否會(huì)有其他線程進(jìn)行修改(set)或者當(dāng)前進(jìn)行修改的資源是否會(huì)有其他線程可以獲取团驱。

  • synchronized——串行訪問
  • volatile——主內(nèi)存刷新,不存在線程副本
  • ThreadLocal——線程空間內(nèi)的全局變量
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末空凸,一起剝皮案震驚了整個(gè)濱河市嚎花,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌呀洲,老刑警劉巖紊选,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異道逗,居然都是意外死亡兵罢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門滓窍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卖词,“玉大人,你說我怎么就攤上這事贰您』灯剑” “怎么了拢操?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舶替。 經(jīng)常有香客問我令境,道長,這世上最難降的妖魔是什么顾瞪? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任舔庶,我火速辦了婚禮,結(jié)果婚禮上陈醒,老公的妹妹穿的比我還像新娘惕橙。我一直安慰自己,他們只是感情好钉跷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布弥鹦。 她就那樣靜靜地躺著,像睡著了一般爷辙。 火紅的嫁衣襯著肌膚如雪彬坏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天膝晾,我揣著相機(jī)與錄音栓始,去河邊找鬼。 笑死血当,一個(gè)胖子當(dāng)著我的面吹牛幻赚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播臊旭,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼落恼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了巍扛?” 一聲冷哼從身側(cè)響起领跛,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撤奸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喊括,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胧瓜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了郑什。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片府喳。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蘑拯,靈堂內(nèi)的尸體忽然破棺而出钝满,到底是詐尸還是另有隱情兜粘,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布弯蚜,位于F島的核電站孔轴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏碎捺。R本人自食惡果不足惜路鹰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望收厨。 院中可真熱鬧晋柱,春花似錦、人聲如沸诵叁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拧额。三九已至浓领,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間势腮,已是汗流浹背联贩。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捎拯,地道東北人泪幌。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像署照,于是被迫代替她去往敵國和親祸泪。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

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

  • 從三月份找實(shí)習(xí)到現(xiàn)在建芙,面了一些公司没隘,掛了不少,但最終還是拿到小米禁荸、百度右蒲、阿里、京東赶熟、新浪瑰妄、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,243評論 11 349
  • Android Handler機(jī)制系列文章整體內(nèi)容如下: Android Handler機(jī)制1之ThreadAnd...
    隔壁老李頭閱讀 7,635評論 4 30
  • Java SE 基礎(chǔ): 封裝映砖、繼承间坐、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務(wù))結(jié)合為一個(gè)獨(dú)立的整體,并盡...
    Jayden_Cao閱讀 2,108評論 0 8
  • Java8張圖 11、字符串不變性 12竹宋、equals()方法劳澄、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,701評論 0 11
  • 昨天天西安下雪了蜈七,美呆了[色](圖來自早上群內(nèi)一朋友曬的雪景圖) 有一起相約北方看雪的嗎秒拔? 我在廣州的寒潮里,蹜蹜...
    艾哥閱讀 254評論 0 1