程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> ThreadLocal簡單理解,threadlocal理解

ThreadLocal簡單理解,threadlocal理解

編輯:JAVA綜合教程

ThreadLocal簡單理解,threadlocal理解


在java開源項目的代碼中看到一個類裡ThreadLocal的屬性:
private static ThreadLocal<Boolean> clientMode = new ThreadLocal<>();


印象中在看書的時候見到過ThreadLocal,但突然就想不起它的用處了。。心裡一驚感覺當時書白看了。於是馬上網上查了查。

  原來它的意思是線程的本地變量,ThreadLocal更像是一個線程變量訪問的工具類。   那為什麼要用這種方法呢? 翻看了《Java並發編程實踐》,看到這麼一個說法:線程本地變量通常用於防止可變單例或者全局變量的設計中,出現不正確的共享。   感覺這個看著很生硬啊。書中也舉了例子,是JDBC的Connection的應用。Connection對於單線程的程序中,一般會啟動時就創建好,這樣就不用每次都創建對象啦。但是換到多線程環境下就不行了,因為JDBC規范並沒有要求Connection是線程安全的。那麼如果要解決就可以使用ThreadLocal。使用ThreadLocal可以在每個線程中創建一個Connection對象,這樣就滿足線程安全要求了。   這裡比較好奇的是ThreadLocal是如何做到這些的呢?   ThreadLocal的實現 打開源代碼,ThreadLocal是個泛型類,裡面也並不復雜,看到的構造函數也是什麼也沒有做。ThreadLocal中比較常用的方法主要是set和get。最主要的奧秘便是下面這幾行代碼:
private final int threadLocalHashCode = nextHashCode();
 
    /**
     * The next hash code to be given out. Updated atomically. Starts at
     * zero.
     */
    private static AtomicInteger nextHashCode =
        new AtomicInteger();
 
    /**
     * The difference between successively generated hash codes - turns
     * implicit sequential thread-local IDs into near-optimally spread
     * multiplicative hash values for power-of-two-sized tables.
     */
    private static final int HASH_INCREMENT = 0x61c88647;
 
    /**
     * Returns the next hash code.
     */
    private static int nextHashCode() {
        return nextHashCode.getAndAdd(HASH_INCREMENT);
    }

threadLocalHashCode這個變量會隨著ThreadLocal構造時創建,而初始化它的是一個nextHashCode()方法。從nextHashCode方法便知道是對一個整形變量nextHashCode進行了一個加法運算,而是固定的增加HASH_INCREMENT大小。

  這樣做是什麼意思呢?其實就是每次創建ThreadLocal時都產生一次新的hash值,就是讓每次的對象不一樣。那麼有何用處?   再看看set方法,因為這個方法是ThreadLocal將變量設置到線程中的方法:
/**
     * Sets the current thread's copy of this thread-local variable
     * to the specified value.  Most subclasses will have no need to
     * override this method, relying solely on the {@link #initialValue}
     * method to set the values of thread-locals.
     *
     * @param value the value to be stored in the current thread's copy of
     *        this thread-local.
     */
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

可以看到方法的執行過程:

1、獲得當前線程的實例 2、然後從線程裡獲取ThreadLocalMap對象,這就是線程裡存本地變量的地方 3、如果map不為空則將value寫入到map中,而key就是當前ThreadLocal的對象 4、如果為null,剛創建map,當然同樣會將value寫入map中,key同樣是ThreadLocal的對象   這樣就理解了,其實ThreadLocal每次產生一個新的對象,以此來保證每個線程都針對一個ThreadLocal對象。然後將數據通過set方法向線程中的threadLocals寫入值,以此來保證線程安全。當然在寫入的value必須不是一個共享對象,否則也是無法保證一定線程安全的。     引用: 《java並發編程實踐》 正確理解ThreadLocal:http://www.iteye.com/topic/103804       注:此文章為原創,歡迎轉載,請在文章頁面明顯位置給出此文鏈接! 若您覺得這篇文章還不錯請點擊下右下角的推薦,非常感謝! http://www.cnblogs.com/5207

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved