“閱讀本文大概需要2分鐘。”
????
看小張有些受驚,我打算換個新的角度。
繼續(xù)問道:剛才說到每個線程只能有一個唯一的looper,你知道android是怎么保證這一點的嗎?
小張眼睛躲避著我的視線,模糊的回答道:我好像記得有個threadLocal和這個有關。
為了給小張一點鼓勵,我說道:沒錯,你說對了,就是它!
小張感覺打了一針強心劑。
我繼續(xù)問道:那threadLocal是怎么做到的呢,你能說具體一點嗎?
小張:我記得threadLocal里面的核心就是一個hashmap,用來保證的。
我來了興趣,繼續(xù)問:那這個hashmap里的key和value分別是什么能達到這個目的?
小張開始支支吾吾...過了一會兒說道:value里存的是looper對象,key存的是...
看到小張期待求助的眼神,我繼續(xù)提示道:你想想key用什么能夠保證線程和looper的唯一映射?肯定是唯一代表線程的東西,對吧?
小張:哦,要是我來設計,會用thread本身來當key來保證這一點。
我看小張還是不很確定,就肯定的說道:沒錯,threadlocal正是用的thread對象本身來當key[注1],這樣每次在thread里創(chuàng)建一個looper時,系統(tǒng)都會先去全局的threadLocal里的hashmap看看對應的線程里是否已經存了looper,如果沒有,就說明這個線程還沒有創(chuàng)建過looper,就正常創(chuàng)建,然后存進hashmap里。如果已經有了,就會報錯。如此一來,每個線程就像在自己的環(huán)境里保存本地變量一樣,互不干擾,這也就是Local的意思。
為了考察小張的學習能力,我又問道:那你覺得threadlocal一般能夠使用在哪些場景呢?它和鎖在使用場景上有啥區(qū)別?。?/p>
小張這次沒有讓我失望,回答道:當開發(fā)過程中需要一個全局變量能夠在多線程場景中使用,而且互不干擾,可以定義一個threadlocal即可,而無需為每個線程定義一個全局靜態(tài)變量,使用起來非常方便。鎖就不一樣了,它是為了保證一個變量在不同的線程之間共享而存在的控制手段。簡而言之,一個是線程獨立,一個是線程共享,場景不同。
聽到這個回答我內心是非常贊賞的,但是作為一名合格的面試官,必須不露聲色。
繼而又問:既然looper是通過threadlocal保證了唯一性,那message queue[注2]唯一性又是如何保證的呢?
小張這次笑了:這個簡單,由于message queue是looper里的一個屬性,looper是線程唯一的,所以message queue也是線程唯一的。
我點了點頭,對小張一輪戰(zhàn)績表示了肯定。
小張感嘆道:沒想到面試還能學習到這么多知識啊...
未完待續(xù)...
[注1]:真正的源碼實現(xiàn)要比這個稍微復雜一些,使用的是ThreadLocalMap,但大體都是map的思想,具體參見源碼。
[注2]:很多同學都讀做Queen(皇后),我內心是崩潰的,正確發(fā)音應該是字母Q,讀對了在我這里面試都會打高一分。
有熱愛Android技術的同學,歡迎加微信公眾號 xh18310039919。用詼諧的方式學習Android硬核知識點。
?????
?????