1. 程式人生 > >ThreadLocal本地執行緒變數的理解

ThreadLocal本地執行緒變數的理解

一般的Web應用劃分為展現層、服務層和持久層三個層次,在不同的層中編寫對應的邏輯,下層通過介面向上層開放功能呼叫。在一般情況下,從接收請求到返回響應所經過的所有程式呼叫都同屬於一個執行緒。
也就是說,同一執行緒貫通N層,不同的執行緒可能由於引數等不同會對程式中的某些變數進行修改,但是又要防止修改後的值對其它執行緒產生影響,因為不同的執行緒可以同時執行滴,這就需要我們解決對某些執行緒共享的變數的訪問衝突問題。ThreadLocal本地執行緒變數就是一種解決方式,它通過將程式中不安全的變數封裝進ThreadLocal中,這相當於為每一個執行緒提供一個獨立的變數副本(其實是不同的物件),執行緒修改變數的值對其它執行緒來說沒影響了,因為其它執行緒有自己的一個副本資訊。

  對於每個執行緒,都有一個類似於Map的東西ThreadLocalMap(ThreadLocal的靜態類 ),那它裡面儲存了什麼東東呢,肯定是key-value啊,key就是上面程式碼中的共享靜態變數 dfThreadLocal,value就是DateFormat例項了,即new SimpleDateFormat(dateFormat)這個東東。那接下來,線上程內我要如何去獲取這個值呢,就是靠dfThreadLocal.get()實現滴,方法原始碼如下:
https://www.cnblogs.com/acanblog/p/6507674.html

   可以很明顯的看出,首先根據Thread.currentThread ()獲取到inheritableThreadLocals(即ThreadLocalMap,他是Thread的一個變數),然後將this(即最上面程式碼的dfThreadLocal物件)作為key(或索引)獲取到真正的值T(就是SimpleDateFormat物件)啊,至此應該比較清楚了。
  為什麼不同的執行緒有各自的值,因為 不同的執行緒—>不同的ThreadLocalMap物件(執行緒的變數)—>通過相同的key(如果有被static修飾)獲取到不同的value值。
  備註:一般都被static修飾,因為可以避免在一個執行緒內可能發生的重複建立TSO(Thread Specific Object,即ThreadLocal所關聯的物件),被statis修飾了,同一執行緒key也肯定一樣,value也肯定只有一份了。
 一個ThreadLocal例項關聯當前執行緒的一個TSO物件,如果把ThreadLocal宣告為例項變數,那麼每建立一個類例項就會導致一個TSO例項誕生,這肯定沒有這個必要滴。