Android 消息機制—ThreadLocal
ThreadLocal 作用
一般來說,當某些數據是以線程為作用域並且不同線程具有不同的數據副本的時候,可以考慮採用 ThreadLocal。ThreadLocal並不是一個thread,而是Thread的局部變數,是一個線程內部的數據存儲類。通過它可以在指定的線程中存儲數據,數據存儲以後,只有在指定線程中可以獲取到存儲的數據,其他線程則無法獲取。當使用ThreadLocal維護變數時,ThreadLocal為每個使用該變數的線程提供獨立的變數副本,而不會影響其他線程所對應的副本。從線程的角度看,目標變數就像是線程的本地變數,這也是類名中Local所要表達的意思。針對這個用法,我們寫個測試demo。
注釋寫的很清楚啦,demo中我們主線程中定義一個全局變數 mIntegerThreadLocal,主線程中設置值為0並列印,子線程 Thread#1 中直接列印變數值,子線程 Thread#2 中設置值為2並列印出來。下面為我們列印日誌:
可以看出,主線程列印值為 0,Thread#1 線程列印值為 null,Thread#2 線程列印值為 2。他們獲取的對象是一樣的,不同線程中獲取到的值是不同的。
ThreadLocal 原理
ThreadLocal是如何做到為每一個線程維護變數的副本的呢?
ThreadLocal 類中有個靜態類 ThreadLocalMap,Thread 中有個變數 threadLocals,類型為ThreadLocal.ThreadLocalMap,就是說每個 Thread 中都有一個 ThreadLocalMap。ThreadLocal 可以根據當前 Thread 去查詢當前 Thread 的 ThreadLocalMap值。不同線程中的 ThreadLocalMap 中存儲的值是不同的。下面我們看一下 ThreadLocal 的內部實現:
set 方法設置當前線程值,方法中先獲取到當前線程,然後根據當前線程獲取到 ThreadLocalMap 對象。如果 map 存在,存儲當前值,如果不存在,調用 createMap 方法創建一個 ThreadLocalMap,並傳入 value 值。
get 方法也是現獲取當前線程,然後根據線程獲取當前線程的 ThreadLocalMap 對象,進而得到存儲的value值。


TAG:全球大搜羅 |