Java8LongAdders:管理并發(fā)計數(shù)器的正確方式-Java開發(fā)Java經(jīng)驗技巧_第1頁
Java8LongAdders:管理并發(fā)計數(shù)器的正確方式-Java開發(fā)Java經(jīng)驗技巧_第2頁
Java8LongAdders:管理并發(fā)計數(shù)器的正確方式-Java開發(fā)Java經(jīng)驗技巧_第3頁
Java8LongAdders:管理并發(fā)計數(shù)器的正確方式-Java開發(fā)Java經(jīng)驗技巧_第4頁
Java8LongAdders:管理并發(fā)計數(shù)器的正確方式-Java開發(fā)Java經(jīng)驗技巧_第5頁
全文預覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、java 8 long adders:管理并發(fā)計數(shù)器的正確方式-編程開發(fā)技術(shù)java 8 longadders:管理并發(fā)計數(shù)器的 正確方式本文ill importnew - will翻譯自takipiblogo歡迎加入翻譯小組。轉(zhuǎn)載詰見文末要求。我只是喜歡新鮮的事物,ifu java 8冇很多新東四。這次我想討論其屮我最喜歡 的之一:并發(fā)加法器。這是一個新的類集合,他們用來管理被多線程讀寫的計數(shù) 器。這個新的api在顯著提升性能同吋,仍然保持了簡單直接的特點。多核架構(gòu)到來之后人們就解決著并發(fā)計數(shù)器,讓我們來看看到現(xiàn)在為止java提 供了哪些解決并發(fā)計數(shù)器的選項,并對比一下他們與新api的性能。

2、臟計數(shù)器-這種方法意味著一個常規(guī)對彖或靜態(tài)屈性正在被多線程讀寫。不幸 的是,由于兩個原因這行不通。原因之一,在java中a += b操作不是原子的。 如果你打開輸出字節(jié)碼,你將至少看到四個指令 第一個用來將屬性值從堆 加載到線程棧,第二個用來加載delta,第三個用來把它們相加,第四個用來將 結(jié)果重新分配給屬性值。如果多個線程同時作用于同一塊內(nèi)存單元,寫操作冇很大機會丟失,因為一個線 程可以覆蓋另一個線程的值(乂名“讀-修改-寫”),另一個令人不快的是這種 情況下你不得不處理值的沖突,述有更壞的情況。這是相當菜鳥的一個問題,而ii超級難調(diào)試。如果你確實發(fā)現(xiàn)有人在你的應(yīng)用中 這么做的話,我想要你

3、幫個小忙。在你的數(shù)據(jù)庫小搜索“tai weiss” ,如果存 在我的記錄,請刪除,這樣我會覺得安全些。synchronized -最基本的并發(fā)用語,它在讀寫一個值的時候會阻塞所有想讀寫 該值的其他線程。雖然它是可行的,但你的代碼卻注定要被轉(zhuǎn)向dmv line。讀寫鎖-基本j&眩鎖的略復雜版本,它使你能夠區(qū)分修改值并且需要阻塞其 他線程的線程和僅是讀取值并且不需要臨界區(qū)的線程。雖然這更有效率(假設(shè)寫 線程數(shù)量很少),但由于當你獲取寫鎖的時候阻塞了所冇其他線程的執(zhí)行,這真 是一個“漂亮”的方法。事實上,只有當你了解到相比讀線程,寫線程的數(shù)量極 大地受限吋它才真正是-個好方法。volatil

4、e -這個關(guān)鍵詞非常容易被誤解,它指示jit編譯器重新優(yōu)化運行時機 器碼,使得屈性的任何修改對其他線程都是即時可見的。這將導致一些jrr處理內(nèi)存分配的順序這項jrr編譯器最喜愛的優(yōu)化失效。你再 說一遍?是的,你沒有聽錯。jit編譯器可以改變屬性分配的順序。這個神秘的小策略(又叫happens-before)能夠最小化程序訪問全局堆的次數(shù),同時仍然 確保你的代碼沒有被影響。真是相當隱蔽 所以什么時候應(yīng)該使用volatile處理計數(shù)器呢?如果你僅有一個線程更新值并 且多個線程讀取它,這時使用volatile無疑是一個真正好的策略。那為什么不總是使用它呢?因為當多個線程同時更新屈性的時候它不能很好的

5、 工作。由于a +二b不是原子操作,這將帶來覆蓋其他寫操作的風險。在java8 之前,處理這種情況你需要使用的是atomiclntegeroatomiclnteger -這組類使用cas (比較并交換)處理器指令來更新計數(shù)器的 值。聽起來不錯,真的是這樣嗎?是也不是。好的一面是它通過一個直接機器碼 指令設(shè)置值時,能夠最小程度地影響其他線程的執(zhí)行。壞的一面是如果它在與其 他線程競爭設(shè)置值時失敗了,它不得不再次嘗試。在高競爭f,這將轉(zhuǎn)化為一個 自旋鎖,線程不得不持續(xù)嘗試設(shè)置值,無限循環(huán)直到成功。這可不是我們想要的 方法。讓我們進入java 8的longaddersojava 8加法器-這是一個如此

6、酷的新api以至于我一宜在滔滔不絕地談?wù)撍?從使用的角度看它與atomiclnteger非常相似,簡單地創(chuàng)建一個longadder實例, 并使用intvalueo和add()來獲取和設(shè)置值。神奇的地方發(fā)生在幕后。這個類所做的事情是當一個直接cas由于競爭失敗時,它將delta保存在為該線 程分配的一個內(nèi)部單元對彖中,然后當intvalue()被調(diào)用時,它會將這些臨時 單-兀的值再相加到結(jié)果和屮。這就減少了返回重新cas或者阻塞其他線程的必 要。多么聰明的做法!好吧,已經(jīng)說的夠多了-讓我們看看這個類的實際表現(xiàn)吧。我們設(shè)立了卜面的基 準測試-通過多線程將一個計數(shù)器增加到10飛。我們用總共10個線

7、程來運行這 個測試-5個寫操作,5個讀操作。測試機器僅有一個四核的i7處理器,因此測 試-定會產(chǎn)生一些嚴重的競爭:dirtyvolatilesynchronizedrwlockatomi1129454弓120911335552591110146791317713267632661079407717157180287312811243662161231849233262108947231636617997531171117453516647155151301411003615174211388672759114m3505170091471623147317500517173169682308197847861729616079928081017.74引m16046158307.73017.;代碼在這里可以下載到注意dirty和volatile都冒著一些嚴重的值覆蓋危險。總結(jié)并行加法器相比原子整數(shù)擁有60%-100%的性能提升執(zhí)行加法的線程之間沒有太大差別,除非被鎖定注意當你使用synchronized或讀寫鎖時所帶來的巨人性能問題-慢一個羨至兩個數(shù) 量級我非常愿意聽到-你已經(jīng)有機會在你的代碼小使用這些類了。*擴展閱讀- brian goe

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論