ThreadLocal源碼學習

概念:
ThreadLocal并不是一個Thread芍瑞,而是一個線程內(nèi)部的存儲類彬坏,可以在指定線程內(nèi)存儲數(shù)據(jù),數(shù)據(jù)存儲以后叉信,只有指定線程可以得到存儲數(shù)據(jù)。

ThreadLocal為解決多線程程序的并發(fā)問題提供了一種新的思路

原理:
當使用ThreadLocal維護變量時艘希,ThreadLocal為每個使用該變量的線程提供獨立的變量副本硼身,所以每一個線程都可以獨立地改變自己的副本,而不會影響其它線程所對應(yīng)的副本覆享。

源碼分析:

  • Implements a thread-local storage, that is, a variable for which each thread
  • has its own value. All threads share the same {@code ThreadLocal} object,
  • but each sees a different value when accessing it, and changes made by one
  • thread do not affect the other threads. The implementation supports

*實現(xiàn)一個線程本地存儲,每個線程的一個變量
*有它自己的價值佳遂。所有線程共享相同的ThreadLocal對象,
*但每看到一個不同的價值當訪問它,和更改
*線程不會影響其他線程

public class ThreadLocal<T> {
可以看出threadlocal是一個范型類,這標志著threadlocal可以存儲所有數(shù)據(jù)

set()方法:
public void set(T value) {
Thread currentThread = Thread.currentThread();//獲取當前運行的線程
Values values = values(currentThread);//返回一個存儲類
if (values == null) {
values = initializeValues(currentThread);//初始化return new Values()
}
values.put(this, value);//插入
}

首先會獲取當前線程撒顿,根據(jù)當前線程獲取Values存儲類丑罪,再調(diào)用values存儲類中的put方法,將內(nèi)容存儲到Values內(nèi)部類的table數(shù)組的下標key.reference中。

values.put():
void put(ThreadLocal<?> key, Object value) {
cleanUp();

        // Keep track of first tombstone. That's where we want to go back
        // and add an entry if necessary.
        int firstTombstone = -1;

        for (int index = key.hash & mask;; index = next(index)) {
            Object k = table[index];

            if (k == key.reference) {
                // Replace existing entry.
                table[index + 1] = value;
                return;
            }

            if (k == null) {
                if (firstTombstone == -1) {
                    // Fill in null slot.
                    table[index] = key.reference;
                    table[index + 1] = value;
                    size++;
                    return;
                }

                // Go back and replace first tombstone.
                table[firstTombstone] = key.reference;
                table[firstTombstone + 1] = value;
                tombstones--;
                size++;
                return;
            }

            // Remember first tombstone.
            if (firstTombstone == -1 && k == TOMBSTONE) {
                firstTombstone = index;
            }
        }
    }

把values的值傳入到一個table數(shù)組的key.reference的下一個下標中
table就以key吩屹,value的形式存儲了線程的本地變量跪另,偶數(shù)位放key,基數(shù)位放value煤搜。
兩個地方不太清楚
1.key.reference 是什么值
2.for (int index = key.hash & mask;; index = next(index)) 條件是什么免绿?

get():
public T get() {
// Optimized for the fast path.
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values != null) {
Object[] table = values.table;
int index = hash & values.mask;
if (this.reference == table[index]) {
return (T) table[index + 1];
}
} else {
values = initializeValues(currentThread);
}

    return (T) values.getAfterMiss(this);
}

方法返回一個當前線程的當前value值,如果這個值沒有初始化擦盾,那么會通過initialValue();返回一個null嘲驾。

remove():

    void remove(ThreadLocal<?> key) {
        cleanUp();

        for (int index = key.hash & mask;; index = next(index)) {
            Object reference = table[index];

            if (reference == key.reference) {
                // Success!
                table[index] = TOMBSTONE;
                table[index + 1] = null;
                tombstones++;
                size--;
                return;
            }

            if (reference == null) {
                // No entry found.
                return;
            }
        }
    }

內(nèi)存釋放,手動釋放當前線程的存儲的值迹卢。

ThreadLocal和線程同步機制相比有什么優(yōu)勢呢辽故?

對于同步機制中來說,通過對象的鎖機制保證同一時間只有一個線程訪問變量腐碱。這時該變量是多個線程共享的誊垢,使用同步機制要求程序慎密地分析什么時候?qū)ψ兞窟M行讀寫,什么時候需要鎖定某個對象喻杈,什么時候釋放對象鎖等繁雜的問題彤枢,程序設(shè)計和編寫難度相對較大狰晚。

對于ThreadLocal來說筒饰,它為每一個線程提供一個獨立的變量副本
,從而隔離了多個線 程對數(shù)據(jù)的訪問沖突壁晒。因為每一個線程都擁有自己的變量副本瓷们,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象秒咐,在編 寫多線程代碼時谬晕,可以把不安全的變量封裝進ThreadLocal,從另一個角度來解決多線程的并發(fā)訪問携取。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末攒钳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子雷滋,更是在濱河造成了極大的恐慌不撑,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晤斩,死亡現(xiàn)場離奇詭異焕檬,居然都是意外死亡,警方通過查閱死者的電腦和手機澳泵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門实愚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事腊敲』魑梗” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵碰辅,是天一觀的道長茫负。 經(jīng)常有香客問我,道長乎赴,這世上最難降的妖魔是什么忍法? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮榕吼,結(jié)果婚禮上饿序,老公的妹妹穿的比我還像新娘。我一直安慰自己羹蚣,他們只是感情好原探,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著顽素,像睡著了一般咽弦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胁出,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天型型,我揣著相機與錄音,去河邊找鬼全蝶。 笑死闹蒜,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的抑淫。 我是一名探鬼主播绷落,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼始苇!你這毒婦竟也來了砌烁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤催式,失蹤者是張志新(化名)和其女友劉穎函喉,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蓄氧,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡函似,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了喉童。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撇寞。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡顿天,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔑担,到底是詐尸還是另有隱情牌废,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布啤握,位于F島的核電站鸟缕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏排抬。R本人自食惡果不足惜懂从,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹲蒲。 院中可真熱鬧番甩,春花似錦、人聲如沸届搁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卡睦。三九已至宴胧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間表锻,已是汗流浹背恕齐。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留浩嫌,地道東北人檐迟。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓补胚,卻偏偏與公主長得像码耐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子溶其,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容

  • ThreadLocal和線程同步機制相比:都是為了解決多線程中相同變量的訪問沖突問題骚腥。在同步機制中,通過對象的鎖機...
    tiancijiaren閱讀 379評論 0 1
  • Android Handler機制系列文章整體內(nèi)容如下: Android Handler機制1之ThreadAnd...
    隔壁老李頭閱讀 7,635評論 4 30
  • 為啥要寫這篇文章 起初我看Handler相關(guān)源碼瓶逃,看到Looper里面有個ThreadLocal束铭,如下,而這個Th...
    xufang2閱讀 2,667評論 4 51
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法厢绝,類相關(guān)的語法契沫,內(nèi)部類的語法,繼承相關(guān)的語法昔汉,異常的語法懈万,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • 分析都是基于android sdk 23 源碼進行的,ThreadLocal在android和jdk中的實現(xiàn)可能并...
    悠嘻俠閱讀 704評論 0 52