2011-07-07 79 views

回答

0

否:不需要外部同步。

java.util.concurrent類中的所有方法都是線程安全的。

+2

線程安全並不意味着您不需要在外部進行同步。我們需要知道地圖的用途。 (出於同樣的原因,在Java中引入了非同步集合類,因爲原始類的「線程安全性」幾乎沒有必要和不足)。 – Thilo

+0

我無法從問題中挑出任何使用信息,當然不足以讓某人倒下。 – Bohemian

+0

這是一個「相對downvote」,使其與Peter的答案相同。如果可以的話,我會提高他兩次。 – Thilo

0

據我所知,所有需要的鎖都是在這個類中完成的,所以如果你沒有做某些特定的事情並且需要它的功能就不需要太擔心。

http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html它說:

不過,儘管所有操作都是線程安全的,檢索操作並不意味着鎖定,並沒有爲防止所有的方式鎖定整個表中的任何支持訪問。

檢索操作(包括get)通常不會阻塞,因此可能與更新操作(包括put和remove)重疊。檢索反映了最近完成的更新操作的結果。

因此,如果這不代表您的特定應用程序中有任何問題,您不必擔心。

1

如果您需要獲取集合的鎖定,則只需要外部同步。該集合不公開其內部鎖。

ConcurrentMap有putIfAbsent,但是如果創建的對象很貴,你可能不想使用它。

final ConcurrentMap<Key, Value> map = 

public Value get(Key key) { 
    // allow concurrent read 
    return map.get(key); 
} 

public Value getOrCreate(Key key) { 
    // could put an extra check here to avoid synchronization. 
    synchronized(map) { 
     Value val = map.get(key); 
     if (val == null) 
      map.put(key, val = new ExpensiveValue(key)); 
     return val; 
    } 
} 
1

是和否。這取決於你在做什麼。 ConcurrentHashMap對於其所有方法(例如get和put)都是線程安全的。但是,對於非原子操作,它是而不是線程安全。這裏是一個例子,其執行非原子操作的方法:

public class Foo { 
    Map<String, Object> map = new ConcurrentHashMap<String, Object>(); 

    public Object getFoo(String bar) { 
     Object value = foo.get(bar); 
     if (value == null) { 
      value = new Object(); 
      map.put(bar, foo); 
     } 
     return value; 
    } 
} 

這裏的缺陷是,它是可能的兩個線程調用getFoo以接收不同的對象。請記住,在處理任何數據結構或類型時,即使像int一樣簡單,非原子操作始終需要外部同步。諸如AtomicInteger和ConcurrentHashMap等類可以幫助使一些常見操作線程安全,但不能防止檢查後設置的操作,如上面的getFoo