424 Stimmen

Java: notify() vs. notifyAll() noch einmal von vorn

Googelt man nach "Unterschied zwischen notify() y notifyAll() ", dann werden viele Erklärungen erscheinen (abgesehen von den javadoc-Absätzen). Es läuft alles auf die Anzahl der wartenden Threads hinaus, die geweckt werden: einer in notify() und alle in notifyAll() .

Allerdings wird (wenn ich den Unterschied zwischen diesen Methoden richtig verstehe) immer nur ein Thread für die weitere Monitor-Erfassung ausgewählt; im ersten Fall derjenige, der von der VM ausgewählt wird, im zweiten Fall derjenige, der vom Thread-Scheduler des Systems ausgewählt wird. Die genauen Auswahlverfahren für beide (im allgemeinen Fall) sind dem Programmierer nicht bekannt.

Was ist das nützlich Unterschied zwischen notify() y notifyAll() dann? Übersehe ich etwas?

6 Stimmen

Die nützlichen Bibliotheken für die Gleichzeitigkeit sind in den Gleichzeitigkeitsbibliotheken zu finden. Ich schlage vor, dass diese in fast jedem Fall die bessere Wahl sind. Die Concurency-Bibliotheken stammen aus der Zeit vor Java 5.0 (wo sie 2004 als Standard hinzugefügt wurden)

4 Stimmen

Ich bin anderer Meinung als Peter. Die Gleichzeitigkeitsbibliothek ist in Java implementiert, und jedes Mal, wenn Sie lock(), unlock() usw. aufrufen, wird eine Menge Java-Code ausgeführt. Man kann sich in den Fuß schießen, wenn man die Gleichzeitigkeitsbibliothek anstelle der guten alten synchronized außer für bestimmte, eher seltene Anwendungsfälle.

4 Stimmen

Das Hauptmissverständnis scheint folgendes zu sein: ... wird immer nur ein Thread für die weitere Monitor-Erfassung ausgewählt; im ersten Fall der von der VM, im zweiten Fall der vom System-Thread-Scheduler ausgewählte. Dies impliziert, dass sie im Wesentlichen gleich sind. Das beschriebene Verhalten ist zwar korrekt, aber es fehlt, dass in der notifyAll() Fall bleiben _die anderen Threads nach dem ersten wach und übernehmen den Monitor, einer nach dem anderen. In dem notify Fall wird keiner der anderen Threads aufgeweckt. Funktionell sind sie also sehr unterschiedlich!

8voto

Steve McLeod Punkte 50514

Von Joshua Bloch, dem Java-Guru persönlich in Effective Java 2nd edition:

"Punkt 69: Bevorzugen Sie Gleichzeitigkeitsprogramme gegenüber Warten und Benachrichtigen".

17 Stimmen

En warum ist wichtiger als die Quelle.

2 Stimmen

@Pacerier Gut gesagt. Ich wäre auch mehr daran interessiert, die Gründe dafür zu erfahren. Ein möglicher Grund könnte sein, dass wait und notify in der Objektklasse auf einer impliziten Bedingungsvariablen beruhen. Im Standard-Producer- und -Consumer-Beispiel..... warten also sowohl Producer als auch Consumer auf dieselbe Bedingung, was zu einem Deadlock führen könnte, wie xagyg in seiner Antwort erklärt. Ein besserer Ansatz ist daher die Verwendung von 2 Bedingungsvariablen, wie sie in docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/

4voto

Spoike Punkte 115938

notify() weckt einen Thread auf, während notifyAll() wird alle aufwecken. Soweit ich weiß, gibt es keinen Mittelweg. Aber wenn Sie nicht sicher sind, was notify() mit Ihren Threads anstellen, verwenden Sie notifyAll() . Funktioniert jedes Mal wie ein Zauber.

4voto

Alle oben genannten Antworten sind richtig, soweit ich das beurteilen kann, also werde ich Ihnen noch etwas anderes sagen. Für Produktionscode sollten Sie wirklich die Klassen in java.util.concurrent verwenden. Es gibt nur sehr wenig, was sie nicht für Sie tun können, wenn es um Gleichzeitigkeit in Java geht.

-2voto

Abhay Bansal Punkte 1

Das Aufwachen aller hat hier keine große Bedeutung. wait notify und notifyall, all diese werden nach dem Besitz des Objektmonitors gesetzt. Wenn ein Thread in der Wartephase ist und notify aufgerufen wird, übernimmt dieser Thread die Sperre und kein anderer Thread kann zu diesem Zeitpunkt die Sperre übernehmen. Ein gleichzeitiger Zugriff kann also gar nicht stattfinden. Soweit ich weiß, kann jeder Aufruf von wait notify und notifyall erst erfolgen, nachdem die Sperre des Objekts übernommen wurde. Korrigieren Sie mich, wenn ich falsch liege.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X