線程局部變量(ThreadLocal)其實的功用非常簡單,就是爲每一個使用該變量的線程都提供一個變量值的副本,是每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本衝突。從線程的角度看,就好像每一個線程都完全擁有一個該變量。
今天動手體驗了一下ThreadLocal的基本功能
帶註釋的是ThreadLocal變量,不帶註釋的是普通string,下面通過模擬三個線程來對比運行結果。
String類型結果:
-1184077754
init:0
-1184077754
init:0
-1184077754
init:0
ThreadLocal類型結果:
-1184077754
init:0
-1184077753
init:1
-1184077752
init:2
由於count靜態變量是線程共享的,在string類型tl賦值時候賦值語句只運行了一遍,count變量始終爲0,並且字符串tl的hashcode始終相同。
而ThreadLocal中get方法返回的string字符串賦值運行了三遍,三個hashcode均不相同,而且count變量也先後爲0 1 2三個不同的值。
說明threadlocal爲每個線程創建了一個本地變量,只有該線程可以訪問,簡單來說,就是把util中的tl複製一份作爲局部變量來使用,避免了多線程對該變量造成的同步問題。
網上找來的模擬代碼來分析一下原理
可以看到實質上ThreadLocal就是一個同步的Map對象,key是當前線程,value是當前線程該變量的值,從而實現了變量線程本地化。
一句話總結,每個線程都會複製一份ThreadLocal申明的變量給自己使用,該變量在每個線程中均是獨立的,其他線程不可訪問的。