Der subtile Unterschied zwischen notify() und notifyAll()
Der Hauptunterschied zwischen notify() und notifyAll() liegt in der Anzahl der wartenden Threads, die sie aktivieren (einer im Vergleich zu allen), wirft dies eine weitere Frage auf:
Warum aktiviert sich immer ein Thread? Objektsperre erneut erwerben?
Im allgemeinen Fall geben sowohl notify() als auch notifyAll() nicht an, welcher wartende Thread ausgewählt wird, um die Sperre erneut zu erwerben. Die JVM oder der System-Thread-Scheduler treffen diese Auswahl, die nicht deterministisch sein kann.
Die Notwendigkeit von notifyAll()
Allerdings ist in bestimmten Szenarien die Verwendung von notify() erforderlich kann zu einem Deadlock führen, wie das folgende Beispiel zeigt:
Producer/Consumer Class with notify()
public class ProducerConsumer { private final int MAX_SIZE = 1; // Buffer size private List<Object> buf = new ArrayList<>(); public synchronized void put(Object o) { while (buf.size() == MAX_SIZE) { wait(); } buf.add(o); notify(); } public synchronized Object get() { while (buf.size() == 0) { wait(); } Object o = buf.remove(0); notify(); return o; } }
Deadlock-Szenario:
Als Infolgedessen warten alle drei Threads auf unbestimmte Zeit, was zu einem Deadlock führt.
Die Lösung: notifyAll()
Um diesen Deadlock aufzulösen, muss man stattdessen notifyAll() verwenden notify() im Producer/Consumer-Code. Dadurch wird sichergestellt, dass alle wartenden Threads aktiviert werden, wodurch Deadlocks vermieden werden.
Empfehlung:
Für die meisten Szenarien ist notifyAll() die bevorzugte Methode, da dadurch potenzielle Deadlocks vermieden werden. Wenn das spezifische Szenario das Aufwecken nur eines bestimmten wartenden Threads erfordert, kann notify() mit Vorsicht verwendet werden.
Das obige ist der detaillierte Inhalt vonWarum erhält ein Thread nach notify() oder notifyAll() immer wieder die Objektsperre?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!