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

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

Inheritable中的ThreadLocal是什么

這篇文章主要介紹“Inheritable中的ThreadLocal是什么”,在日常操作中,相信很多人在Inheritable中的ThreadLocal是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Inheritable中的ThreadLocal是什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

瑞安ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話(huà)聯(lián)系或者加微信:028-86922220(備注:SSL證書(shū)合作)期待與您的合作!

1、簡(jiǎn)介 在上一篇 ThreadLocal詳解 中,我們?cè)敿?xì)介紹了ThreadLocal原理及設(shè)計(jì),從源碼層面上分析了ThreadLocal。但由于ThreadLocal設(shè)計(jì)之初就是為了綁定當(dāng)前線(xiàn)程,如果希望當(dāng)前線(xiàn)程的ThreadLocal能夠被子線(xiàn)程使用,實(shí)現(xiàn)方式就會(huì)相當(dāng)困難(需要用戶(hù)自己在代碼中傳遞)。在此背景下,InheritableThreadLocal應(yīng)運(yùn)而生。

Inheritable thread-local variables are used in preference to ordinary thread-local variables when the per-thread-attribute being maintained in the variable (e.g., User ID, Transaction ID) must be automatically transmitted to any child threads that are created.

2、應(yīng)用 調(diào)用鏈追蹤:在調(diào)用鏈系統(tǒng)設(shè)計(jì)中,為了優(yōu)化系統(tǒng)運(yùn)行速度,會(huì)使用多線(xiàn)程編程,為了保證調(diào)用鏈ID能夠自然的在多線(xiàn)程間傳遞,需要考慮ThreadLocal傳遞問(wèn)題(大多數(shù)系統(tǒng)會(huì)使用線(xiàn)程池技術(shù),這已經(jīng)不僅僅是InheritableThreadLocal能夠解決的了,我會(huì)在另外一篇文章中介紹相關(guān)技術(shù)實(shí)現(xiàn))。

3、InheritableThreadLocal類(lèi) InheritableThreadLocal類(lèi)重寫(xiě)了ThreadLocal的3個(gè)函數(shù):

`/**
 * 該函數(shù)在父線(xiàn)程創(chuàng)建子線(xiàn)程,向子線(xiàn)程復(fù)制InheritableThreadLocal變量時(shí)使用
 */
protected T childValue(T parentValue) {
    return parentValue;
}
/**
 * 由于重寫(xiě)了getMap,操作InheritableThreadLocal時(shí),
 * 將只影響Thread類(lèi)中的inheritableThreadLocals變量,
 * 與threadLocals變量不再有關(guān)系
 */
ThreadLocalMap getMap(Thread t) {
   return t.inheritableThreadLocals;
}
/**
 * 類(lèi)似于getMap,操作InheritableThreadLocal時(shí),
 * 將只影響Thread類(lèi)中的inheritableThreadLocals變量,
 * 與threadLocals變量不再有關(guān)系
 */
void createMap(Thread t, T firstValue) {
    t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
}`

注意:由于重寫(xiě)了getMap()和createMap()兩個(gè)函數(shù),所以當(dāng)

4、線(xiàn)程間傳值實(shí)現(xiàn)原理 說(shuō)到InheritableThreadLocal,還要從Thread類(lèi)說(shuō)起:

public class Thread implements Runnable {
......(其他源碼)
/* 
 * 當(dāng)前線(xiàn)程的ThreadLocalMap,主要存儲(chǔ)該線(xiàn)程自身的ThreadLocal
 */
ThreadLocal.ThreadLocalMap threadLocals = null;

/*
 * InheritableThreadLocal,自父線(xiàn)程集成而來(lái)的ThreadLocalMap,
 * 主要用于父子線(xiàn)程間ThreadLocal變量的傳遞
 * 本文主要討論的就是這個(gè)ThreadLocalMap
 */
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
......(其他源碼)

}`

Thread類(lèi)中包含 threadLocals 和 inheritableThreadLocals 兩個(gè)變量,其中 inheritableThreadLocals 即主要存儲(chǔ)可自動(dòng)向子線(xiàn)程中傳遞的ThreadLocal.ThreadLocalMap。 接下來(lái)看一下父線(xiàn)程創(chuàng)建子線(xiàn)程的流程,我們從最簡(jiǎn)單的方式說(shuō)起:

4.1、用戶(hù)創(chuàng)建Thread, Thread thread = new Thread();

4.2、Thread創(chuàng)建

public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}

4.3、Thread初始化

/**
 * 默認(rèn)情況下,設(shè)置inheritThreadLocals可傳遞
 */
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize) {
    init(g, target, name, stackSize, null, true);
}
/**
 * 初始化一個(gè)線(xiàn)程.
 * 此函數(shù)有兩處調(diào)用,
 * 1、上面的 init(),不傳AccessControlContext,inheritThreadLocals=true
 * 2、傳遞AccessControlContext,inheritThreadLocals=false
 */
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc,
                  boolean inheritThreadLocals) {
    ......(其他代碼)

    if (inheritThreadLocals && parent.inheritableThreadLocals != null)
        this.inheritableThreadLocals =
            ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);

    ......(其他代碼)
}`

可以看到,采用默認(rèn)方式產(chǎn)生子線(xiàn)程時(shí),inheritThreadLocals=true;若此時(shí)父線(xiàn)程inheritableThreadLocals不為空,則將父線(xiàn)程inheritableThreadLocals傳遞至子線(xiàn)程。

4.4、ThreadLocal.createInheritedMap 讓我們繼續(xù)追蹤createInheritedMap:

`static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
    return new ThreadLocalMap(parentMap);
}
    /**
     * 構(gòu)建一個(gè)包含所有parentMap中Inheritable ThreadLocals的ThreadLocalMap
     * 該函數(shù)只被 createInheritedMap() 調(diào)用.
     */
    private ThreadLocalMap(ThreadLocalMap parentMap) {
        Entry[] parentTable = parentMap.table;
        int len = parentTable.length;
        setThreshold(len);
        // ThreadLocalMap 使用 Entry[] table 存儲(chǔ)ThreadLocal
        table = new Entry[len];

        // 逐一復(fù)制 parentMap 的記錄
        for (int j = 0; j < len; j++) {
            Entry e = parentTable[j];
            if (e != null) {
                @SuppressWarnings("unchecked")
                ThreadLocal key = (ThreadLocal) e.get();
                if (key != null) {
                    // 可能會(huì)有同學(xué)好奇此處為何使用childValue,而不是直接賦值,
                    // 畢竟childValue內(nèi)部也是直接將e.value返回;
                    // 個(gè)人理解,主要為了減輕閱讀代碼的難度
                    Object value = key.childValue(e.value);
                    Entry c = new Entry(key, value);
                    int h = key.threadLocalHashCode & (len - 1);
                    while (table[h] != null)
                        h = nextIndex(h, len);
                    table[h] = c;
                    size++;
                }
            }
        }
    }`

從ThreadLocalMap可知,子線(xiàn)程將parentMap中的所有記錄逐一復(fù)制至自身線(xiàn)程。

5、總結(jié) InheritableThreadLocal主要用于子線(xiàn)程創(chuàng)建時(shí),需要自動(dòng)繼承父線(xiàn)程的ThreadLocal變量,方便必要信息的進(jìn)一步傳遞。

到此,關(guān)于“Inheritable中的ThreadLocal是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!


文章名稱(chēng):Inheritable中的ThreadLocal是什么
當(dāng)前URL:http://weahome.cn/article/gsgoph.html

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部