2012-05-02 30 views
1

根據以下答案: 目前還不清楚:如果有任何問題,那麼concurrentMap上的synchronized結構會做什麼。即在同時映射的情況下,在同步(映射)與非同步之間有什麼區別。 我對解決方案的正確性或相信的好處不感興趣。只是對這個問題的回答: 問:同步映射上的同步和不同步上的區別是什麼?具體就性能而言..就足夠了。沒有更多請。
我只對發生什麼事情感興趣,沒有任何補充建議。在同步集合上進行同步 - >性能問題

我有一個理論問題,我有一點精神問題的解決: 假設我有一個Concurrent集合類say => ConcurrentHashMap map;

假設我有三個方法:

method1: synchronized(map){ 
     doSomethingWithThemap(); //Assume put integers 1.. 1000000 
} 

method2:doSomethingWithThemap(); //Note it is not synchronized 
method3:doSomethingElseWithThemap(); //Assume put integers 2000000.. 3000000 

現在假設2度的TestCase:


  • TestCase1:產卵兩個線程一個& B. A調用方法1和B調用方法3。
  • TestCase2:產生兩個線程A'& B'。 '調用method2和B'調用method3。

從性能上看我希望TestCase2獲勝,因爲從我的理解,在TestCase1 B不能添加到地圖中,儘管同時,由於同步塊將保留在地圖上的鎖, TestCase2並不是這種情況。

我的單元測試不驗證這個假設。

問:我在這裏錯過了什麼。即給定同步集合上的同步塊是否會影響性能?

+0

method1將100萬整數放入地圖中,method2做了什麼? – esej

+0

非同步塊中完全一樣的東西。 –

回答

2

問:我在這裏錯過了什麼。

你的假設,即ConcurrentHashMap內部同步本身是不正確的:根據the source code,實現使用java.util.concurrent.locks對象,它們的實例隱藏在內部的集合,讓你無法鎖定/對它們進行同步。

一般來說,這是一個建議,類庫的作者應該遵循:如果你需要在一個對象上同步,不要在this上同步;在你的類中創建一個私有對象,然後在該對象上進行同步。否則,您可能面臨由其他人在您的對象上同步引起的併發問題,並無限期地持有鎖。

+0

'ConcurrentHashMap'的意義在於它沒有一個單一的全局鎖,你必須保持與地圖一起工作 - 你可以有許多線程同時寫入和讀取它。這就是爲什麼'Hashtable'和'Maps.synchronizedMap(HashMap)'更好。 –

+0

對我仍然不清楚:如果有任何問題,那麼concurrentMap上的同步構造會做什麼。即在同時映射的情況下,在同步(映射)與非同步之間有什麼區別。 我對解決方案的正確性或相信的好處不感興趣。我對它的功能感興趣。 –

+0

@OlivierTwist在你的情況下,它什麼都不做,因爲你的線程是唯一同步的線程。 'concurrentMap'在其他東西上同步,這是實現的內部特性。如果其他線程在'concurrentMap'上同步,則只有其中一個線程正在執行其同步塊。但是,您還可以在任何其他非空對象上同步;它是你的'concurrentMap'的事實是完全不相關的。 – dasblinkenlight

0

您不能保證ConcurrentHashMap將其實例用作監視器。它可能非常使用其他對象來鎖定!

private Object lock = new Object(); 

synchronized(lock) { 
    // do some stuff - you can't get my lock because it is private 
} 

這是一個ConcurrentHashMap不使用鎖,但甚至有可能,而一些其他的併發原語類似的比較和設置,信號燈等。

Java中的鎖是可重入的,所以如果你已經持有一個鎖,你不會阻止自己。

0

ConcurrentHashMap沒有使用synchronized ...儘管如此,仍然線程安全,但獲取調用例如沒有鎖定任何東西。併發數據結構非常好,很有趣。那麼它確實在某些情況下使用了一些內部鎖定,但沒有暴露出來,並且肯定不會暴露對象的顯示器本身。

順便說一句。像這樣測量併發代碼的性能是相當棘手的,並且隨着運行和計算機的不同而不同,但無論如何它們大都是有缺陷的。

但是,否則它理論上可以像你所描述的那樣工作,如果你使用同步hashmap代替。 Collections.synchronizedMap(yourMap);

0
What does the synchronized construct on the concurrentMap do, if anything 

它只是浪費時間和空間。 ConcurrentMap已經體現了處理併發的其他方法。