真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

ThreadLocal原理是什么

這篇文章主要介紹ThreadLocal原理是什么,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

成都創(chuàng)新互聯(lián)公司專注于祁縣網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供祁縣營銷型網(wǎng)站建設(shè),祁縣網(wǎng)站制作、祁縣網(wǎng)頁設(shè)計(jì)、祁縣網(wǎng)站官網(wǎng)定制、微信小程序開發(fā)服務(wù),打造祁縣網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供祁縣網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

ThreadLocal即線程局部變量的意思!所以什么是線程局部變量?這玩意有什么鳥用?是不是面試被問到了說不出個(gè)一二三?今天就來扒一扒這貨的源碼,從根本上了解這貨是干啥的。

Thread、ThreadLocalMap、Entry三者關(guān)系

其實(shí)研究下來他的源碼實(shí)現(xiàn),其實(shí)也沒想象的那么復(fù)雜,其最主要有以下幾點(diǎn):

1、Java可以通過Thread.currentThread()來獲得當(dāng)前的Thread的實(shí)例對(duì)象。既然能拿到這Thread對(duì)象實(shí)例,那么我們就可以操作該實(shí)例(的屬性),比如為該Thread對(duì)象設(shè)置一個(gè)值什么。

2、每一個(gè)Thread對(duì)象都有一個(gè)ThradLocalMap實(shí)例,該實(shí)例有一個(gè)一個(gè)Entry組成的數(shù)組,Entry對(duì)象有兩個(gè)主要屬性:value和ThreadLocal的弱引用,其中value這個(gè)屬性就是值設(shè)置給當(dāng)前線程所持有,也是ThreadLocal的核心屬性:

static class Entry extends WeakReference> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal k, Object v) {
        super(k);
        value = v;
    }
}

注意Entry繼承自WeakReference,其key就是ThreadLocal對(duì)象?。▓D1)

ThreadLocal原理是什么

結(jié)合1和2兩個(gè)知識(shí)點(diǎn),我們就可以知道我們拿到Thread對(duì)象之后,就可以操控當(dāng)前線程對(duì)象的ThreadLocalMap對(duì)象,然后把想要保存的value交給ThreadLocalMap的Entry的value屬性,Thread,ThreadLocalMap,value三者之間的關(guān)系可以用下圖表示(圖2):

ThreadLocal原理是什么

通過上圖我們可以得出這么一個(gè)結(jié)論:一個(gè)Thread對(duì)象持有一個(gè)ThreadLocalMap對(duì)象,然后呢,一個(gè)ThreadLoalMap對(duì)象又包含了多個(gè)ThreadLlocal對(duì)象及ThreadLocal對(duì)象所在線程的value?。?!一言以蔽之: 一個(gè)Thread對(duì)象可以持有多個(gè)ThreadLocal對(duì)象的變量值value

那么ThreadLocal和Thread又有啥關(guān)系呢?二者是怎能對(duì)value進(jìn)行讀取的呢?下面就根據(jù)源碼來簡(jiǎn)單的分析下。

ThreadLocal和Thread的關(guān)聯(lián)

先看看ThreadLocal的set方法:

 public void set(T value) {
         //獲取當(dāng)前線程
        Thread t = Thread.currentThread();
        //獲取當(dāng)前線程持有的ThreadLocalMap
        ThreadLocal.ThreadLocalMap map = getMap(t);
        //將value設(shè)置給threadlocalMap
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

set方法很邏輯很簡(jiǎn)單(j結(jié)合上圖2看更好理解):

1、通過currentThread方法拿到當(dāng)前Thread對(duì)象

2、獲取當(dāng)前Thread對(duì)象的ThreadLoalMap對(duì)象

3、將value連同ThreadLocal對(duì)象自己組成一個(gè)Entry對(duì)象保存在

ThreadLoalMap的Entry類型的數(shù)組中。

在來看看ThreadLocal的get方法:

public T get() {
    //獲取當(dāng)前線程
    Thread t = Thread.currentThread();
    //獲取當(dāng)前線程的ThreadLocalMap對(duì)象
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        //獲取與ThreadLocal對(duì)象想關(guān)聯(lián)的value
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            //獲取值
            T result = (T)e.value;
            return result;
        }
    }
    //為空返回初始化值
    return setInitialValue();
}

可以發(fā)展get的整體邏輯也很簡(jiǎn)單:

1、獲取當(dāng)前Thread對(duì)象

2、獲取當(dāng)前Thread對(duì)象的ThreadLocalMap對(duì)象

3、從ThreadLocalMap中獲取與ThreadLocal相關(guān)聯(lián)的Entry對(duì)象,具體的就是以ThreadLocal為key獲取。

4、獲取步驟3的Entry的value屬性,并返回之。

通過整體觀察get和set方法可以得出如下結(jié)論:ThreadLocal對(duì)象調(diào)用set方法就是往Thread對(duì)象的ThreadLocalMap里面添加值;ThreadLocal對(duì)象調(diào)用get方法就是從Thread對(duì)象的ThreadLocalMap里面獲取值。核心就是操縱Thread對(duì)象的ThreadLocalMap對(duì)象進(jìn)行value的讀和寫。原理就這么簡(jiǎn)單。

那么位于不同線程的不同ThreadLocal對(duì)象,在其他線程里保存值是一個(gè)什么樣的關(guān)系呢?可以通過下圖來清晰的描述出來:

ThreadLocal原理是什么

ThreadLocal的使用實(shí)例

我們?cè)谥涝贏ndroid中一個(gè)線程只有一個(gè)Looper對(duì)象,那么是怎么做到的呢?就是ThreadLocal發(fā)揮了作用,看看Looper的prepare方法:

//定義一個(gè)靜態(tài)的ThreadLocal變量
static final ThreadLocal sThreadLocal = new ThreadLocal(); 

private static void prepare(boolean quitAllowed) {
        //一個(gè)Thread只能關(guān)聯(lián)一個(gè)Looper對(duì)象
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

觀察prepare方法可以知道,先通過sThreadLocal的get方法判斷當(dāng)前線程是否已經(jīng)擁有了一個(gè)Looper對(duì)象,如果有就拋出一個(gè)異常;如果當(dāng)前線程還沒有設(shè)置Looper對(duì)象,則調(diào)用ThreadLocal的set方法,初始化一個(gè)Looper對(duì)象交給當(dāng)前線程:

sThreadLocal.set(new Looper(quitAllowed));

這樣就確保了一個(gè)線程只有一個(gè)Looper對(duì)象。

到此為止,關(guān)于ThreadLocal的原理已經(jīng)基本分析完畢,至于內(nèi)部是怎么set和get的,博主并沒有做太細(xì)的分析,因?yàn)闆]必要,了解ThreadLocal的工作原因以及使用場(chǎng)景即可。

以上是ThreadLocal原理是什么的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


本文名稱:ThreadLocal原理是什么
文章鏈接:http://weahome.cn/article/pjsege.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部