2016-03-29 10 views
1

ich die gleichzeitige Hash-Karte hält einige Ergebnisse verwenden möchten,ConcurrentHashMap Update existiert Wert Thread-sicher

ConcurrentHashMap<Long,AtomicInteger> 

einen neuen Eintrag hinzufügen, wenn Schlüssel nicht vorhanden ist, oder der Wert von Schlüssel und Zuwachs erhalten, wie folgt aus:

if(map.contains(key)) 
    map.get(key).addAndGet(1); 
else 
    map.put(key,new AtomicInteger(1));  

die Put-Operation ist nicht thead sicher, wie dieses Problem zu lösen? Ist der Put-Vorgang innerhalb eines synchronisierten Blocks?

+2

Es ist nicht nur die Put-Operation - der gesamte angezeigte bedingte Block müsste in einem synchronisierten Block liegen. Alternativ können Sie 'putIfAbsent' verwenden. –

+0

Die Verwendung des PutIfAbsent scheint einfacher. Ich habe den doppelten Check in synchronisierten Block verwendet, anstatt den gesamten bedingten Block zu verwenden. – raymond

Antwort

2

Die Operation put() selbst ist threadsafe implementiert, d. H., Wenn Sie denselben Schlüssel setzen, wird er intern synchronisiert.

Der Aufruf ist jedoch nicht, d. H. Zwei Threads könnten gleichzeitig einen neuen Schlüssel hinzufügen. Sie könnten versuchen, putIfAbsent() und wenn Sie einen Rückgabewert (d. H. Nicht null) erhalten, könnten Sie die get-Methode aufrufen.

//this only adds a new key-value pair if there's not already one for the key 
if(map.putIfAbsent(key,new AtomicInteger(1)) != null) {  
    map.get(key).addAndGet(1); 
} 

Alternativ, wenn Sie Java 8 verwenden sind könnten Sie die compute() Methode verwenden, die nach dem JavaDoc atomar ausgeführt wird: So können Sie Ihren Code wie folgt ändern. Die übergebene Funktion würde dann prüfen, ob der Wert bereits existiert oder nicht. Da der gesamte Aufruf synchronisiert wird, brauchen Sie wahrscheinlich nicht einmal eine AtomicInteger (hängt davon ab, was Sie sonst mit dem Wert tun).

0

Sie sollten die ConcurrentHashMap.putIfAbsent(K key, V value) verwenden und achten Sie auf den Rückgabewert.

Verwandte Themen