簡體   English   中英

同步代碼比非同步代碼執行得更快

[英]Synchronized code performs faster than unsynchronized one

我出來了這個驚人的結果,我絕對不知道原因:我有兩種方法縮寫為:

private static final ConcurrentHashMap<Double,Boolean> mapBoolean = 
        new ConcurrentHashMap<Double, Boolean>();
private static final ConcurrentHashMap<Double,LinkedBlockingQueue<Runnable>> map
        = new ConcurrentHashMap<Double, LinkedBlockingQueue<Runnable>>();


protected static <T> Future<T> execute(final Double id, Callable<T> call){
// where id is the ID number of each thread
synchronized(id)
{
   mapBoolean.get();// then do something with the result
   map.get();//the do somethign with the result
}
}

protected static <T> Future<T> executeLoosely(final Double id, Callable<T> call){

 mapBoolean.get();// then do something with the result
 map.get();//the do somethign with the result

 }

}

在使用超過500個線程進行性能分析,並且每個線程分別調用上述每個方法400次時,我發現execute(..)執行至少比executeLoosely(..)好500倍,這很奇怪,因為executeLoosely不同步,因此更多線程可以同時處理代碼。

任何原因?

在我假設沒有500個核心的機器上使用500個線程的開銷,使用大約100-1000x的任務,只要在Map上執行查找以執行JVM可以檢測到的代碼就沒有做任何事情,是可能產生隨機結果。 ;)

您可能遇到的另一個問題是,使用synchronized執行更快的測試可以從使用synchronized中受益,因為它會偏向對一個線程的訪問。 即它將您的多線程測試變回單線程測試,這是最快的。

您應該將您獲得的時間與執行循環的單個線程進行比較。 如果這更快(我相信它會),那么它不是一個有用的多線程測試。

我的猜測是你在非同步代碼之后運行同步代碼。 即JVM已經預熱了一點。 交換執行這些測試的順序並多次運行它們會得到不同的結果。

在非同步場景中:1)等待獲取地圖段上的鎖定,鎖定,對地圖執行操作,解鎖,等待獲取其他地圖的某個段的鎖定,鎖定,在其他地圖上執行操作,開鎖。 段級鎖定僅在並發寫入段的情況下執行,在您的示例中看起來不是這種情況。

在同步方案中:1)等待鎖定,執行兩個操作,解鎖。

上下文切換所需的時間會產生影響嗎? 運行測試的機器有多少個核心? 地圖是如何構建的,同樣的鍵?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM