2016-04-15 9 views
-1

Ich frage mich, ob es threadsicher ist, eine gleichzeitige HashSet in Java zu verwenden, in der gleichzeitige Schreibvorgänge von mehr als 1 Threads auftreten können, wenn wir garantieren können, dass jeder Thread() hinzufügen kann/entfernen() nur einen eindeutigen Wertgleichzeitige Schreibvorgänge von eindeutigen Werten zu einem Java HashSet

kann beispielsweise ein Gewinde() hinzufügen/entfernen() zu/von einem der HashSet seine eigenen ID)

I auf jedem Fall gelesen habe, dass, wenn Es gibt gleichzeitige Schreibvorgänge in einem HashSet, es ist nicht Thread-sicher aber ich nicht tun Warum verstehe ich das in meinem vorherigen Beispiel? Da jeder Thread nur einen eindeutigen Wert (wie threadID) hinzufügen (/ threadID) kann, der nicht aus einem anderen Thread hinzugefügt oder entfernt wird und daher keine Abhängigkeiten zwischen den Threads-Einfügungen und Löschungen bestehen, warum nicht das thread-sicher?

Schließlich gibt es mehr intelligente Art und Weise dies zu implementieren, anstatt ein ConcurrentHashMap zu schaffen, die Schlüssel mit leeren Werten enthält?

EDIT: Ich habe this post gelesen, aber meine Frage wird immer noch nicht beantwortet. Ich verstehe nicht, warum die HashSet durch gleichzeitige Schreiben von verschiedenen Werte beeinflusst werden kann.

+0

Vielleicht können Sie die Info [hier] (http://stackoverflow.com/questions/6992608/why-there-isno-concurrenthashset-against-concurrenthashmap) verwenden. – dquijada

+0

Bitte lesen Sie sorgfältig meine Frage. – dinosaur

+0

Warum? Weil [die Dokumentation] (https://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html) dies sagt. Es kann sein, dass gleichzeitige Schreibvorgänge * keine Probleme verursachen, aber es gibt keine Garantie für dieses Verhalten, daher sollte man sich nicht darauf verlassen. –

Antwort

0

HashSet und HashMap, verwenden Sie einen Hash-Mechanismus, um zu bestimmen, in welchen Bucket der neue Eintrag eingefügt werden soll. Im Allgemeinen wird dies nicht vom parallelen Zugriff beeinflusst, solange die Schlüssel eindeutig sind.

Bucket-Größen werden sorgfältig überwacht, da die Performance stark ansteigt, wenn sie zu groß werden. Wenn der Eimer eines HashSet zu voll wird, wird resize ausgelöst. Dies ordnet alle Eimer in eine bessere Anordnung um.

Wenn ein anderer Thread zu schreiben versucht/Lese während ein resize ist sehr wahrscheinlich ist, dass der Prozess zum Absturz bringen wird als die Struktur in der Mitte ist neu geordnet zu werden.

Wenn normale Synchronisierungsmechanismen zu beschwerlich erscheinen, können Sie besser eine ReadWriteLock verwenden. Einige Anwendungshinweise finden Sie unter here.

+0

Das ist eine nette Antwort! Vielen Dank! – dinosaur

+0

Diese Antwort schlägt vor, dass es in Ordnung sein wird, das HashSet gleichzeitig zu ändern. Das ist einfach falsch. – Raedwald

+1

Nein, es zeigt das genaue Problem an, das auftreten kann. Lesen Sie den 3. Teil genauer. – dinosaur