一切從android的handler說起(二)之threadLocal

 閱讀本文大概需要2分鐘。

 

 

看小張有些受驚,我打算換個新的角度。

 

繼續問道:剛纔說到每個線程只能有一個唯一的looper,你知道android是怎麼保證這一點的嗎?

小張眼睛躲避着我的視線,模糊的回答道:我好像記得有個threadLocal和這個有關。

 

爲了給小張一點鼓勵,我說道:沒錯,你說對了,就是它!

小張感覺打了一針強心劑。

 

我繼續問道:那threadLocal是怎麼做到的呢,你能說具體一點嗎?

小張:我記得threadLocal裏面的核心就是一個hashmap,用來保證的。

 

我來了興趣,繼續問:那這個hashmap裏的key和value分別是什麼能達到這個目的?

小張開始支支吾吾...過了一會兒說道:value裏存的是looper對象,key存的是...

 

                                                       

 

看到小張期待求助的眼神,我繼續提示道:你想想key用什麼能夠保證線程和looper的唯一映射?肯定是唯一代表線程的東西,對吧?

小張:哦,要是我來設計,會用thread本身來當key來保證這一點。

 

我看小張還是不很確定,就肯定的說道:沒錯,threadlocal正是用的thread對象本身來當key[注1],這樣每次在thread裏創建一個looper時,系統都會先去全局的threadLocal裏的hashmap看看對應的線程裏是否已經存了looper,如果沒有,就說明這個線程還沒有創建過looper,就正常創建,然後存進hashmap裏。如果已經有了,就會報錯。如此一來,每個線程就像在自己的環境裏保存本地變量一樣,互不干擾,這也就是Local的意思。

 

爲了考察小張的學習能力,我又問道:那你覺得threadlocal一般能夠使用在哪些場景呢?它和鎖在使用場景上有啥區別啊?

小張這次沒有讓我失望,回答道:當開發過程中需要一個全局變量能夠在多線程場景中使用,而且互不干擾,可以定義一個threadlocal即可,而無需爲每個線程定義一個全局靜態變量,使用起來非常方便。鎖就不一樣了,它是爲了保證一個變量在不同的線程之間共享而存在的控制手段。簡而言之,一個是線程獨立,一個是線程共享,場景不同。

 

聽到這個回答我內心是非常讚賞的,但是作爲一名合格的面試官,必須不露聲色。

繼而又問:既然looper是通過threadlocal保證了唯一性,那message queue[注2]唯一性又是如何保證的呢?

小張這次笑了:這個簡單,由於message queue是looper裏的一個屬性,looper是線程唯一的,所以message queue也是線程唯一的。

 

我點了點頭,對小張一輪戰績表示了肯定。

小張感嘆道:沒想到面試還能學習到這麼多知識啊...

 

未完待續...

 

[注1]:真正的源碼實現要比這個稍微複雜一些,使用的是ThreadLocalMap,但大體都是map的思想,具體參見源碼。

[注2]:很多同學都讀做Queen(皇后),我內心是崩潰的,正確發音應該是字母Q,讀對了在我這裏面試都會打高一分。

 



有熱愛Android技術的同學,歡迎加 QQ羣 726464410,或者掃描QQ羣二維碼 和 微信公衆號二維碼。用詼諧的方式學習Android硬核知識點。

                       

                                                                              歡迎轉發,關注公衆號
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章