ThreadLocal簡單理解,threadlocal理解

來源:互聯網
上載者:User

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.