一、定義
threadlocal會為每乙個執行緒提供乙個獨立的變數副本,從而隔離了多個執行緒對資料的訪問衝突。因為每乙個執行緒都擁有自己的變數副本,從而也就沒有必要對該變數進行同步了。threadlocal提供了執行緒安全的共享物件,在編寫多執行緒**時,可以把不安全的變數封裝進threadlocal。
概括起來說,對於多執行緒資源共享的問題,同步機制採用了「以時間換空間」的方式,而threadlocal採用了「以空間換時間」的方式。前者僅提供乙份變數,讓不同的執行緒排隊訪問,而後者為每乙個執行緒都提供了乙份變數,因此可以同時訪問而互不影響。
但是要注意,雖然threadlocal能夠解決上面說的問題,但是由於在每個執行緒中都建立了副本,所以要考慮它對資源的消耗,比如記憶體的占用會比不使用threadlocal要大。
二、基本使用
示例
public static void main(string args) else}system.out.println(thread.currentthread().getname() + " " + threadlocal.get());
}).start();
}system.out.println(thread.currentthread().getname() + " " + threadlocal.get());
}
輸出結果:
main 999thread-0 2000
thread-1 2000
thread-2 2000
上述示例說明:執行緒與執行緒之間相互隔離,且執行緒安全。threadlocal作用域為當前執行緒
三、原始碼分析
threadlocal為什麼可以做到每乙個執行緒都有乙份變數的副本,其實原理很簡單
threadlocal原理同hashmap原理是一樣的,核心為threadlocalmap,只不過是map的key為當前執行緒,通過thread.currentthread()獲取。只要是在同乙個執行緒內,只要你執行set方法,這個key永遠保持不變,即每乙個執行緒對應乙個value。
我們先通過threadlocal的set方法來分析
// set方法一般都是set(key, value),因為threadlocalmap使用了當前執行緒作為key,所以省略了,get()方法也一樣。public void set(t value)
threadlocalmap getmap(thread t)
void createmap(thread t, t firstvalue)
首次在呼叫 set方法時,會執行createmap,在createmap方法中又會建立乙個threadlocalmap物件,我們再來看一下threadlocalmap這個構造方法
構造方法
threadlocalmap(threadlocal<?> firstkey, object firstvalue)
通過構造方法,我們可以看出threadlocal底層使用的就是hashmap結構
threadlocalmap繼承了weakreference
static class threadlocalmap}private static final int initial_capacity = 16;
private entry table;
}
threadlocal為什麼要使用弱引用?
首先我們看乙個weakhashmap的示例,weakhashmap也是它的 entry類繼承了weakreference
public static void main(string args) throws interruptedexceptionkey = null;
key2 = null; // 不會被**
system.gc();
system.out.println(weakmap); //
}
我們可以看出weakhashmap針對key作了**,而在整個map中並沒有真正的**此物件。在threadlocal中,它使用當前執行緒作為key的,如果執行緒生命週期結束後,即這個key以及對就的value都應該被gc掉
記憶體洩露問題
雖然上述的弱引用解決了key,也就是執行緒的threadlocal能及時被**,但是value卻依然存在記憶體洩漏的問題。當把threadlocal例項置為null以後,沒有任何強引用指向threadlocal例項,所以threadlocal將會被gc**。map裡面的value卻沒有被**.而這塊value永遠不會被訪問到了。所以存在著記憶體洩露,因為存在一條從current thread連線過來的強引用。只有當前thread結束以後, current thread就不會存在棧中,強引用斷開, current thread, map, value將全部被gc**.
threadlocal和synchonized的比較:
當然threadlocal並不能替代synchronized,它們處理不同的問題域。synchronized用於實現同步機制,比threadlocal更加複雜。
ThreadLocal實現原理與原始碼分析
threadlocal底層實現內部類 threadlocalmap 一 threadlocal的set方法原始碼分析 1 public void set t value thread t thread.currentthread threadlocalmap map getmap t if map ...
ThreadLocal原始碼理解
threadlocal其實原理是建立了多份相同資料儲存在堆記憶體上,每個執行緒的thread類裡有threadlocal.threadlocalmap threadlocals的屬性來指向存位置,所以每個執行緒修改都不會影響到其他執行緒的資料 首先說下下面用到的東西 threadlocalmap為t...
ThreadLocal原始碼分析
在理解handler looper之前,先來說說threadlocal這個類,聽名字好像是乙個本地執行緒的意思,實際上它並不是乙個thread,而是提供乙個與執行緒有關的區域性變數功能,每個執行緒之間的資料互不影響。我們知道使用handler的時候,每個執行緒都需要有乙個looper物件,那麼and...