ThreadLocal原理和 java類全局靜態變量在多線程中數據混亂問題


一般想要在不同方法中傳遞上下文數據,會使用全局變量,而想在不同類中傳遞上下文數據,則會使用全局靜態變量,因為靜態全局變量是屬於類一直存在的,但是在多線程操作狀態下,java類全局靜態變量在多線程中會出現數據混亂問題,因為多個線程同時對同一個靜態變量操作時,無法確保每個線程取出的值是自己放的值。
這時就出現了ThreadLocal
ThreadLocal眾所周知,可以把變量綁定到到某一線程上,這個thread里有個靜態內部類(可以理解為一個全局變量ThreadLocalMap),

 

 其泛型為<ThreadLocal,Object> 

而threadlocal在執行set方法時會先獲取當前線程(Thread t = Thread.currentThread()),使用當前線程去拿到一個ThreadLocalMap,如果這個map不為空,說明當前線程之前有綁定過的map,就更新這個這個map的value,如果沒有就以自身為key把值放到map中,從而實現變量與線程的綁定。

 

 

 

 關於ThreadLocal的用法,有這兩種說法

1.傳遞上下文變量,減少程序復雜度

2.空間換時間,解決並發下對臨界資源的訪問。

 

其次還要注意的是:ThreadLocal和同步機制synchonzied相比

Synchronized用於線程間的數據共享,而ThreadLocal則用於線程間的數據隔離。

1.1.synchonzied同步機制是為了實現同步多線程對相同資源的並發訪問控制。同步的主要目的是保證多線程間的數據共享。同步會帶來巨大的性能開銷,所以同步操作應該是細粒度的(對象中的不同元素使用不同的鎖,而不是整個對象一個鎖)。如果同步使用得當,帶來的性能開銷是微不足道的。使用同步真正的風險是復雜性和可能破壞資源安全,而不是性能。 

2.ThreadLocal以空間換取時間,提供了一種非常簡便的多線程實現方式。因為多個線程並發訪問無需進行等待,所以使用ThreadLocal會獲得更大的性能。

3.ThreadLocal中的對象,通常都是比較小的對象。另外使用ThreadLocal不能使用原子類型,只能使用Object類型。ThreadLocal的使用比synchronized要簡單得多。 

4.synchronized是利用鎖的機制,使變量或代碼塊在某一時該只能被一個線程訪問。而ThreadLocal為每一個線程都提供了變量的副本,使得每個線程在某一時間訪問到的並不是同一個對象,這樣就隔離了多個線程對數據的數據共享。而Synchronized卻正好相反,它用於在多個線程間通信時能夠獲得數據共享。 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM