2017-01-03 7 views
0

Ich habe diesen Code:Hinzufügen und Werte von ConcurrentHashMap entfernen, während über sie iterieren

private ConcurrentMap<String, Integer> myMap = new ConcurrentHashMap<>(); 

@Scheduled(fixedDelay = 600_000) 
public void foo(){  
    myMap.values().stream(). 
       filter(predicate()). 
       forEach(this::remove); 
} 

public void insert(String str, Integer value){ 
    myMap.put(str, value); 
} 

Was würde passieren, wenn während über diese Karte Iterieren - jemand einen neuen Wert in ihm oder entfernt einen vorhandenen Wert daraus stellen wird ?

+0

Haben Sie etwas versucht? –

+0

@BuhakeSindi - nicht sicher, ich verstehe, was Sie fragen – Noam

+0

Was ich sage ist, haben Sie einen Testfall erstellt, der Ihrem Szenario entspricht. –

Antwort

4

Die Dokumentation für ConcurrentHashMap enthält einige Details zum Verhalten. Zuerst schauen wir uns an, was ConcurrentHashMap.values() tut:

Gibt eine Collection Ansicht der Werte in dieser Karte enthaltenen ...

Die Iteratoren und spliterators Sicht sind schwach konsistente.

Die spliterator Sicht Berichte Spliterator.CONCURRENT und Spliterator.NONNULL.

Interessant sind die Begriffe "weakly consistent" und Spliterator.CONCURRENT, wo der ehemalige wie beschrieben wird:

meisten gleichzeitige Sammlung Implementierungen (einschließlich der meisten Queues) unterscheiden sich auch von den üblichen java.util Konventionen, dass ihre Iteratoren und Spliterators bieten schwach konsistente anstatt schnell scheitern Traversal:

  • können sie gleichzeitig mit anderen Operationen
  • gehen sie ConcurrentModificationException
  • sie nie garantiert werfen Elemente zu durchlaufen, wie sie genau einmal auf Bau bestanden und kann (aber nicht garantiert) spiegeln alle Änderungen nach Konstruktion.

und Spliterator.CONCURRENT werden wie folgt beschrieben:

Kennwert bedeutet, daß die Elementquelle sicher gleichzeitig modifiziert werden kann (so dass Hinzufügungen, Ersetzungen und/oder Entfernungen) durch mehrere Threads ohne externe Synchronisation. Wenn dies der Fall ist, erwartet der Spliterator eine dokumentierte Richtlinie bezüglich der Auswirkungen von Modifikationen während des Traversierens.

Von all diesen Dokumentationen und mit der Gleichzeitigkeit Modell der ConcurrentHashMap konsistent zu sein, bedeutet dies, dass die Stream-Pipeline vollständig threadsicher ist und die Elemente durchlaufen, wie sie bei der Schaffung des Iterators existierten.

+1

Danke! Nach der Frage von @BuhakeSindi habe ich versucht, einen Komponententest zu erstellen, der mehrere Threads verwendet, die Elemente aus dieser Map hinzufügen und entfernen (einige zum Einfügen und einige zum Entfernen) - und während dieser Zeit habe ich meine foo() -Methode ausgeführt und in der Tat - kein Schaden wurde angerichtet ... – Noam

Verwandte Themen