2014-01-13 63 views
4

我可以看到ReentrantLock比​​和AtomicInteger快了約50%。爲什麼與這三種同步方法的執行時間存在差異:​​blocks,ReentrantLockAtomicInteger(或Atomic包中的任何類)。同步vs ReentrantLock vs AtomicInteger執行時間

除了這些之外,還有其他流行的和擴展的同步方法嗎?

+3

你究竟是如何得到這些表現數字的?由於JIT和GC,Java中的微代碼非常棘手。您可以輕鬆獲得誤導性結果。 – Jesper

+0

我認爲你的意思是'java.util。併發'包 –

+0

我只是使用'System.nanoTime()',它不是一個詳盡的測試,我給的percentajes只是指示性的。 – dabadaba

回答

5

AtomicInteger比硬件上的其他兩種同步方法快得多,因爲它是無鎖的。在CPU爲無鎖併發提供基本設施的體系結構上,完全採用硬件完成操作,其中關鍵通常採用單個CPU指令。相比之下,ReentrantLock和​​使用多個指令來執行他們的任務,所以你會看到一些相關的開銷。

+0

無鎖是什麼意思? – dabadaba

+0

@dabadaba這意味着'AtomicInteger'上的操作不會無限期地阻塞其他線程,從而允許線程作爲一個組來總是取得一些進展。 – dasblinkenlight

+0

或多或少意味着它不能與其他線程一起工作,但在另一個層次上,在硬件層面上呢? – dabadaba

9

一些因素影響這一點。

  • Java的版本。對於ReentrantLock來說Java 5.0速度要快很多,Java 7並沒有太多的爭用程度
  • 。同步效果最好(一般情況下鎖定)和低爭用率。 ReentrantLock在更高的爭用率下工作得更好。 YMWV
  • JIT可以做多少優化。 JIT優化以ReentrantLOck不同的方式進行優化。如果這是不可能的,你不會看到優勢。
  • 同步是GC免費的行動。 ReentrantLock可以創建垃圾,使其更慢,並根據使用方式觸發GC。

AtomicInteger使用相同的原語,鎖定使用但忙於等待。 CompareAndSet也稱爲CompareAndSwap,即它的功能簡單得多(並且受到更多限制)

ConcurrentXxxx,CopyOnWriteArrayXxxx集合非常受歡迎。這些提供了併發性,而不需要直接使用鎖(在某些情況下根本沒有鎖)

+0

你的爭論是什麼意思?你的回答符合ReentrantLock比同步更慢,我在結果中看到了相反的結果,請再次檢查我的帖子。或者,也許我誤解了你的迴應。 – dabadaba

+0

@dabadaba yes有時ReentrantLock速度更快,有時速度更慢。這一切都取決於我上面列出的因素。即使你的CPU架構可以有所作爲。我看過一個例子,其中具有相同JVM的相同代碼在不同型號的CPU上運行(在PC上,而在另一臺筆記本上)運行速度明顯不同。 –

+0

@dabadaba爭用意味着有多少CPU在同一時間試圖使用相同的資源。每個資源只需一個線程即可進行測試。 –

1

我認爲你在評估這3個元素進行比較時會犯一個常見的錯誤。

基本上,當ReentrantLock與同步密鑰相比,當您正在同步塊時,可以讓您更靈活。原子是採用基於CAS(比較和交換)的不同方法來管理併發上下文中的更新的東西。

我建議你閱讀一本深入Java平臺的併發聖經。

Java Concurrency in Practice - Brian Göetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes & Doug Lea

有一個在其上併發有深入的瞭解,並知道什麼是語言可以爲您提供解決併發問題,並採取多線程的特性有很大的區別。

就性能而言,它取決於當前情況。