Java多線程之ThreadLocal總結

原貼地址:http://www.cnblogs.com/zhengbin/p/5674638.htmlhtml

閱讀目錄測試

官方對ThreadLocal的描述:

  "該類提供了線程局部(thread-local)變量。這些變量不一樣於它們的普通對應物,由於訪問某個變量(經過其get或set方法)的每一個線程都有本身的局部變量,它獨立於變量的初始化副本。ThreadLocal實例一般是類中的private static字段,它們但願將狀態與某一個線程(例如,用戶ID或事物ID)相關聯。"this

《Thinking in Java》中的描述:

  防止任務在共享資源上產生衝突的第二種方式是根除對變量的共享。線程本地存儲是一種自動化機制,能夠爲使用變量的每一個不一樣的線程都建立不一樣的存儲。所以,若是你有5個線程都要使用變量x所表示的對象,那線程本地存儲就會生成5個用於x的不一樣的存儲塊。主要是,它們使得你能夠將狀態與線程關聯起來。線程

三個要點:

  1.每一個線程都有本身的局部變量

    每一個線程都有一個獨立於其它線程的上下文來保存這個變量,一個線程的本地變量對其它線程是不可見的。設計

  2.獨立於變量的初始化副本

    ThreadLocal能夠給一個初始值,而每一個線程都會得到這個初始化值的一個副本,這樣才能保證不一樣的線程都有一份拷貝。3d

  3.狀態與某一個線程相關聯

    ThreadLocal不是用於解決共享變量的問題的,不是爲了協調線程同步而存在,而是爲了方便每一個線程處理本身的狀態而引入的一個機制,就像《Thinking in  Java》中描述的那樣:」它們使得你能夠將狀態與線程關聯起來。「理解這點對正確使用ThreadLocal相當重要。code

源碼舉例:

  從輸出的結果能夠看出,五個線程處理本身的本地變量值。htm

  而這個測試的結果,並無相同。這是由於實例爲對象,因此初始值爲一個對象的引用,那麼五個線程的副本就是這個對象的引用的副本,也就是說這些引用仍是指向同一個對象,因此就出現了這種狀況。對象

ThreadLocal的接口方法:

  • void set(T value):設置當前線程的線程局部變量的值;
 
 1 public void set(T value) {
 2    Thread t = Thread.currentThread();
 3    ThreadLocalMap map = getMap(t);
 4 
 5    if (map != null)
 6      map.set(this, value);
 7   //說明線程第一次使用線程本地變量(注意這裏的第一次含義)
 8    else
 9        createMap(t, value);
10 }
  • public T get():該方法返回當前線程所對應的線程局部變量;
 1 public T get() {
 2   //獲取當前執行線程
 3   Thread t = Thread.currentThread();
 4   //取得當前線程的ThreadLocalMap實例
 5   ThreadLocalMap map = getMap(t);
 6   //若是map不爲空,說明該線程已經有了一個ThreadLocalMap實例
 7   if (map != null) {
 8     //map中保存線程的全部的線程本地變量,咱們要去查找當前線程本地變量
 9     ThreadLocalMap.Entry e = map.getEntry(this);
10     //若是當前線程本地變量存在這個map中,則返回其對應的值
11     if (e != null)
12          return (T)e.value;
13   }
14    //若是map不存在或者map中不存在當前線程本地變量,返回初始值
15    return setInitialValue();
16 }
  • public void remove():將當前線程局部變量的值刪除,目的是爲了減小內存的佔用,該方法是JDK 5.0新增的方法。當線程結束後,對應該線程的局部變量將被自動垃圾回收,因此顯示調用該方法清除線程的局部變量並非必須的操做,但它能夠加快內存回收的速度;
  • protected T initialValue():返回該線程局部變量的初始值,該方法是一個protected的方法,顯然是爲了讓子類覆蓋而設計的,這個方法是一個延遲調用方法,在線程第1次調用get()或set(T)時才執行,而且僅執行1次。ThreadLocal中的默認實現直接返回一個null。

       這裏注意,ThreadLocal中是有一個Map,但這個Map不是咱們平時使用的Map,而是ThreadLocalMap,ThreadLocalMap是ThreadLocal的一個內部類,不對外使用的。當使用ThreadLocal存值時,首先是獲取到當前線程對象,而後獲取到當前線程本地變量Map,最後將當前使用的ThreadLocal和傳入的值放到Map中,也就是說ThreadLocalMap中存的值是[ThreadLocal對象, 存放的值]這樣作的好處是,每一個線程都對應一個本地變量的Map,因此一個線程能夠存在多個線程本地變量。下面提供一個簡單的實現版本:blog

相關文章
相關標籤/搜索