一般想要在不同方法中傳遞上下文數據,會使用全局變量,而想在不同類中傳遞上下文數據,則會使用全局靜態變量,因為靜態全局變量是屬於類一直存在的,但是在多線程操作狀態下,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卻正好相反,它用於在多個線程間通信時能夠獲得數據共享。