延迟分析中的案例研究:锁定与同步
特別是在這篇文章中,我們將討論:
- java.concurrent.Lock創建的垃圾
- 比較鎖與同步
- 如何以編程方式測量延遲
- 爭用對鎖和同步的影響
- 協調遺漏對延遲測試的影響
回到我最喜歡的主題之一,垃圾創建/分配。 有關此主題的更多詳細信息,請參閱我以前的文章(例如,性能優化 的第一條規則和重新訪問 性能優化 的第一條規則:逃逸分析的效果 )。 特別是為什么分配是理解性能問題的如此關鍵因素。
幾天前,在嘗試診斷JIT編譯過程中分配的一些奇怪影響時,我遇到了一個問題,即java.util.concurrent.locks.ReentrantLock分配,但僅當處于競爭狀態時才進行分配。 (這可以通過運行一個測試程序(如以下程序)輕松地證明,使用– verbosegc在Lock上創建競爭)。
下面的競爭鎖的gc輸出示例:
[GC (Allocation Failure) 16384K->1400K(62976K), 0.0016854 secs] [GC (Allocation Failure) 17784K->1072K(62976K), 0.0011939 secs] [GC (Allocation Failure) 17456K->1040K(62976K), 0.0008452 secs] [GC (Allocation Failure) 17424K->1104K(62976K), 0.0008338 secs] [GC (Allocation Failure) 17488K->1056K(61952K), 0.0008799 secs] [GC (Allocation Failure) 17440K->1024K(61952K), 0.0010529 secs] [GC (Allocation Failure) 17408K->1161K(61952K), 0.0012381 secs] [GC (Allocation Failure) 17545K->1097K(61440K), 0.0004592 secs] [GC (Allocation Failure) 16969K->1129K(61952K), 0.0004500 secs][GC (Allocation Failure) 17001K->1129K(61952K), 0.0003857 secs]我想知道清理這些分配所必需的垃圾回收是否意味著在高度競爭的環境中,與使用內置的“ synchronized ”相比, Lock在同步方面是更糟糕的選擇。
當然,這個問題比其他任何事情都更具學術性。 如果您確實非常在意延遲,那么您將永遠(或者肯定永遠不會)陷入需要大量線程鎖定的情況。 不過,因為過程和結果很有趣,所以請和我在一起。
有點歷史。 鎖于2004年在Java 1.5版中引入。迫切需要將Lock與其他并發實用程序一起使用,以簡化并發構造。 到那時為止,您已經處理了Object上的內置synchronized和wait()notify() 。
ReentrantLock除了提供synchronized功能外,還提供許多功能,
這僅僅是列舉的一小部分:
- 非結構化–即您不限于在塊或方法中使用它。 它使您可以通過幾種方法持有鎖。
- 鎖定輪詢
- 超時等待鎖
- 可配置的公平政策
但是,它們在延遲測試方面的表現如何?
我在下面編寫了一個簡單的測試,比較了鎖與同步的性能。
- 該代碼使您可以更改線程數(1個線程表示沒有爭用),從而調整爭用量。
- 在有或沒有協同遺漏的情況下進行測量(請參閱以前的博客《協調遺漏的效果》 )
- 運行測試鎖定或同步測試。
- 要記錄我的結果,您會注意到我使用了Histogram類。 這是由彼得·勞瑞(Peter Lawrey)創建的。 你可以找到類為紀事核心在實用這里 。
結果如下:
這些是忽略了遺漏的結果:
- 時間以微秒為單位。
- 延遲分布在圖的頂部。
- 此測試中的爭用意味著要使用4個線程運行該程序。
- 測試在具有8個邏輯CPU的MBP i7上運行。
- 每個測試包括200,000,000次迭代和10,000次迭代預熱。
- 調整協調遺漏時的吞吐量為1迭代/微秒。
正如預期的那樣,在沒有爭用的情況下,結果幾乎相同。 JIT將優化鎖定并進行同步。
在較低的百分位數中,使用Lock進行爭用稍微快一些,但實際上又不是很多。 因此,即使有許多較小的垃圾收集,它們似乎也沒有顯著降低鎖的速度。 如果有的話,總體上Lock會稍微快一點。
這些是為協調省略而調整的結果。
這些數字當然更高,因為它們考慮了引起的真正延遲。
同樣,在沒有爭用的情況下,鎖和同步執行相同的操作–在那里沒有很大的驚喜。
有了爭用,現在我們可以看到高達99%的百分比的同步鎖定性能超出10倍。 之后,時間幾乎相同。
我可以推測,與同步相比,gc集合的影響(介于300-1200微秒之間)是導致鎖緩慢的原因。 尤其是因為速度下降僅出現到第99個百分位時才明顯–在此之后,延遲可能會降到硬件和操作系統上。 但是,這只是我的推測,無需進一步調查。
結論
這篇文章的收獲更多是關于衡量和分析延遲的過程。 有趣的是, Lock在競爭時進行分配,但不太可能在現實世界中產生任何實際變化
翻譯自: https://www.javacodegeeks.com/2015/08/a-case-study-in-analysing-latency-lock-vs-synchronized.html
總結
以上是生活随笔為你收集整理的延迟分析中的案例研究:锁定与同步的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tostring 16进制_ToStri
- 下一篇: hmac hmac.new_使用HMAC