Java SE 8 在併發工具方面的加強

infoq發表於2014-04-20

  Java 8在Lambda表示式、介面預設方式、新的日期API等方面引入的新特性廣受關注,同時在併發程式設計方面也做出了大量改進。以往的幾個Java版本都對java.util.concurrent做了不同程度的增強,比如Java 7的Fork/Join框架,而Java 8則進一步在java.util.concurrent下增加了新的介面、類與方法。目前java.util.concurrent的官方文件已經更新,變更部分總結如下:

 新的類以及介面

  java.util.concurrent 中增加了兩個介面四個類:

  1. CompletableFuture.AsynchronousCompletionTask介面:標識在async方法中執行的非同步任務。
  2. CompletionStage<T>介面:非同步計算中可能出現的一個階段,也就是說當一個CompletionStage 完成時執行的動作或計算。
  3. CompletableFuture<T>類:一個可以確定完成狀態的Future。有關CompletableFuture的詳細用法可參考NoBlogDefFound上的《Java 8: CompletableFuture in action》一文。
  4. ConcurrentHashMap.KeySetView<K,V>類:ConcurrentHashMap 的鍵的集合檢視。
  5. CountedCompleter<T>類:一個在沒有其他action等待的情況下,會執行一個完成action的 ForkJoinTask 。
  6. CompletionException類:異常類。

 ConcurrentHashMap增加新方法

  在Java 8中,集合框架基於streams和Lambda表示式做了全新調整:

  ConcurrentHashMap增加了30多個方法,包括foreach系列(forEach,forEachKey, forEachValue, forEachEntry)、search系列(search, searchKeys, searchValues, searchEntries)、reduce系列(reduce, reduceToDouble, reduceToLong)以及mappingCount 、newKeySet等方法, 增強後的ConcurrentHashMap更適合做快取了, 讀者可以看看這篇用ConcurrentHashMap類和lambda表示式實現本地快取的文章。

 java.util.concurrent.atomic包的改進

  java.util.concurrent.atomic包中增加了四個新的類:DoubleAccumulator、DoubleAdder、LongAccumulator、 LongAdder,這四個類的作者是併發大師Doug lea。

  原有的Atomic系列類通過CAS來保證併發時操作的原子性,但是高併發也就意味著CAS的失敗次數會增多,失敗次數的增多會引起更多執行緒的重試,最後導致AtomicLong的效率降低。新的四個類通過減少併發,將單一value的更新壓力分擔到多個value中去,降低單個value的“熱度”以提高高併發情況下的吞吐量,京東的劉錕洋詳細分析了LongAdder的原始碼,另外minddotout的博主在早些時候對LongAdder、AtomicLong進行了效能測試,我們從結果中也可以直觀的看到 LongAdder的強大。

 ForkJoinPool中增加新方法

  Java 8除了對Fork-Join框架做了優化外,也為ForkJoinPool增加了兩個靜態方法:getCommonPoolParallelism() 、commonPool(),Oleg Shelajev在這篇博文中對Fork/Join做了詳細的介紹並做了測試以比較其在JDK7、JDK8中的效能。

 增加StampedLock類

  StampedLock是一種新型鎖的實現,很可能在大多數場景都可以替代ReentrantReadWriteLock。它為讀寫操作提供了三種模式:Writing、ReadingOptimistic、 Reading。

  有關Java 8併發程式設計方面特性的詳細介紹可從官方文件獲取。

相關文章