CAS,AtomicXXX類抽米,LongAdder

CAS和Atomic類參考:https://www.pdai.tech/md/java/thread/java-thread-x-juc-AtomicInteger.html#%E4%BD%BF%E7%94%A8%E4%B8%BE%E4%BE%8B


LongAdder類

LongAdder是jdk8新增的用于并發(fā)環(huán)境的計數(shù)器。雖然AtomicLong/AtomicInt使用了CAS操作在并發(fā)環(huán)境下避免了加鎖锁荔,當出現(xiàn)競爭CAS失敗時,AtomicLong/AtomicInt的邏輯很簡單,就是無限循環(huán)重復CAS敷硅,直到成功。在高并發(fā)環(huán)境下墓赴,如果有大量線程同時更新計數(shù)器竞膳,同一時間只有會一個線程更新成功,而其他線程都會因為更新失敗而空轉诫硕,大大降低了效率坦辟。而LongAdder維護了一個計數(shù)器數(shù)組,不同的線程可能更新計數(shù)數(shù)組中的不同元素章办,從而導致同一時間多個線程能夠成功更新計數(shù)器锉走,大大提高了高并發(fā)環(huán)境下的更新效率滨彻。本質上,LongAdder是一種以空間換時間的設計挪蹭。


成員變量:


base是一個長整型的變量亭饵,是基礎的計數(shù)器變量。當沒有線程競爭更新時梁厉,LongAdder使用base技術辜羊,此時的LongAdder與AtomicLong基本相同。

cells是計數(shù)器數(shù)組词顾,當出現(xiàn)多線程同時更新LongAdder時八秃,會使用cells計數(shù)。cells和它的成員cell使用的是懶加載肉盹,只有出現(xiàn)競爭真正需要使用數(shù)組時才會初始化昔驱。

cellsBusy是一個標志位,只有0和1兩個值上忍,用于實現(xiàn)CAS鎖骤肛。當LongAdder中一段代碼快需要互斥加鎖時,就調用casCellsBusy方法窍蓝,嘗試CAS將cellsBusy置1腋颠,失敗的線程就不進入代碼塊。成功進入代碼塊的線程執(zhí)行完畢后它抱,將cellsBusy置0秕豫,釋放鎖。


內部類Cell:

Cell類很簡單观蓄,就一個變量value用于計數(shù)混移,和一個cas方法使用UnSafe的CAS操作更新value值。在cell上有一個@Contended注解侮穿,它的作用是防止更新計數(shù)器時出現(xiàn)偽共享問題歌径。


[補充]JMM中的緩存行與偽共享問題:

簡單來說,計算機在CPU和內存之間使用了緩存技術亲茅,從而導致了可見性問題回铛。當計算機將數(shù)據(jù)從內存讀入緩存時,是以一個緩存行(64K)為單位讀入的克锣,這樣茵肃,當一個CPU更新了緩存行中的一個變量,計算機會將整個緩存行重新寫入內存袭祟,而其他CPU中該緩存行中所有變量都會失效验残。這就出現(xiàn)了當更新一個變量后同一緩存行的另一個變量在緩存中就失效了,讀取的時候需要重新在內存中讀巾乳,大大降低了效率您没。@Contended標簽通過在變量周圍填充空白鸟召,使一個緩存行中只有一個變量,解決了偽共享問題氨鹏。

具體參考:http://www.reibang.com/p/e338b550850f


如何確定cells數(shù)組中的哪個cell為當前線程計數(shù):

LongAdder會使用UnSafe初始化一個隨機變量保存到當前線程中欧募,之后每次使用UnSafe從當前線程中取出該變量對數(shù)組長度取余,得到該線程使用cells中哪個槽計數(shù)仆抵。從而將不同線程隨機分配到不同槽中計數(shù)跟继。


核心方法:

add方法?

將計數(shù)器增加x。邏輯如下:

情況1:當cells沒有初始化時(沒有線程競爭)镣丑,LongAdder使用base計數(shù)还栓,CAS修改base,若成功传轰,方法結束。

情況2:如果cells已經初始化了(出現(xiàn)了線程競爭)谷婆,找到當前線程在cells數(shù)組中的計數(shù)槽慨蛙,如果該槽中cell對象已經存在,CAS更新cell纪挎,若成功期贫,方法結束。

其他情況:進入longAccumulate方法异袄。


add方法流程圖

longAccumulate方法

longAccumulate代碼非常復雜通砍,根據(jù)不同的情況會有不同的處理流程。

情況1:因為CAS修改base失敗進入該方法烤蜕,此時cells為空封孙,longAccumulate創(chuàng)建cells數(shù)組和一個cell槽,使用cells數(shù)組來計數(shù)讽营。新建的cells數(shù)組長度只有2虎忌,它會在之后cell出現(xiàn)線程競爭時擴容。


cells創(chuàng)建流程

注意橱鹏,為了線程安全膜蠢,保證只有一個線程創(chuàng)建cells數(shù)組,線程會先嘗試獲取cellsBusy鎖莉兰,如果已經有其他線程在創(chuàng)建cells挑围,即獲取鎖失敗,當前線程會再次嘗試使用base計數(shù)糖荒,如果依舊失敗杉辙,則循環(huán)longAccumulate方法。

情況2:該線程使用的cell對象還未初始化而進入該方法寂嘉。


LongAdder新建一個cell對象奏瞬,成功獲取鎖后枫绅,將cell放入cells數(shù)組中的位置。

情況3:線程CAS更新對應的cell時競爭失敗硼端,進入該方法并淋。

longAccumulate會先再嘗試一次CAS更新cell,如果依舊失敗珍昨,就會選擇擴容cells或者調用advanceProbe方法修改線程中的變量值县耽,使當前線程使用cells中的另一個cell來計數(shù)。是否擴容取決于cells長度是否超過cpu核心數(shù)镣典,如果超過兔毙,擴容將沒有意義。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末兄春,一起剝皮案震驚了整個濱河市澎剥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赶舆,老刑警劉巖哑姚,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異芜茵,居然都是意外死亡叙量,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門九串,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绞佩,“玉大人,你說我怎么就攤上這事猪钮∑飞剑” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵烤低,是天一觀的道長谆奥。 經常有香客問我,道長拂玻,這世上最難降的妖魔是什么酸些? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮檐蚜,結果婚禮上魄懂,老公的妹妹穿的比我還像新娘。我一直安慰自己闯第,他們只是感情好市栗,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般填帽。 火紅的嫁衣襯著肌膚如雪蛛淋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天篡腌,我揣著相機與錄音褐荷,去河邊找鬼。 笑死嘹悼,一個胖子當著我的面吹牛叛甫,可吹牛的內容都是我干的。 我是一名探鬼主播杨伙,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼其监,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了限匣?” 一聲冷哼從身側響起抖苦,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎米死,沒想到半個月后睛约,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡哲身,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了贸伐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勘天。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖捉邢,靈堂內的尸體忽然破棺而出脯丝,到底是詐尸還是另有隱情,我是刑警寧澤伏伐,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布宠进,位于F島的核電站,受9級特大地震影響藐翎,放射性物質發(fā)生泄漏材蹬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一吝镣、第九天 我趴在偏房一處隱蔽的房頂上張望堤器。 院中可真熱鬧,春花似錦末贾、人聲如沸闸溃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辉川。三九已至表蝙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乓旗,已是汗流浹背府蛇。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留寸齐,地道東北人欲诺。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像渺鹦,于是被迫代替她去往敵國和親扰法。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349