Wartenbekämpfung Szene
Die typische Wartungsszene bezieht sich im Allgemeinen mit den folgenden zwei Inhalten:
1. Zustandsvariable
Wenn Themen warten müssen, wird es immer durch einige Bedingungen verursacht. Wenn Sie beispielsweise die Warteschlange einfügen, muss der Thread, wenn das Warteschlangenelement voll ist, aufhören zu laufen. Wenn die Warteschlangenelemente frei sind, setzen Sie ihre eigene Ausführung fort.
2. Bedingungspräprädikat
Wenn der Thread festgelegt wird, ob die Wartezeit eingeben oder von Benachrichtigungen aufwacht, müssen Sie testen, ob die Statusbedingungen erfüllt sind. Wenn Sie beispielsweise Elemente zur Warteschlange hinzufügen, ist die Warteschlange voll und blockiert. Wenn andere Threads das Element aus der Warteschlange abnehmen, hat die Warteschlange den verbleibenden Speicherplatz in der Warteschlange, die dem Warten hinzugefügt werden kann Faden." Zu diesem Zeitpunkt wird das Warten auf das Element geweckt und beurteilen Sie dann, ob es wirklich Platz für die aktuelle Warteschlange gibt. Nächstes Wake -up.
3. Zustandswarteschlange
Jedes Objekt verfügt über eine erstellte Warteschlange.
Beachten
Warten und Benachrichtigung sind ein wichtiger Bestandteil des Java -Synchronisationsmechanismus. In Kombination mit synchronisierten Schlüsselwörtern können viele hervorragende synchrone Modelle hergestellt werden, wie z. B. das Hersteller-Verbrauchermodell. Wenn Sie jedoch die Funktion von Function (), Notify (), NotifyAll () verwenden, müssen Sie den folgenden Punkten besondere Aufmerksamkeit schenken:
Wait (), Notify (), NotifyAll () -Methoden gehören nicht zur Thread -Klasse, sondern zur Objektfundamentklasse, dh jedes Objekt hat die Funktionen von Wait (), benachrichtigen () und benachrichtigen (). Da jedes Objekt gesperrt ist, ist die Schloss die Grundlage für jedes Objekt, sodass die Methode der Betriebsschloss auch die grundlegendste ist.
Rufen Sie OBJs Warte () und melden Sie () an, Sie müssen die OBJ -Sperre erhalten, dh Sie müssen in das synchronisierte (OBJ) {...} -Codebegment geschrieben sein.
Nach dem Aufrufen von obj.wait () wird der Thread A die Sperre von OBJ veröffentlicht, ansonsten kann der Thread B die OBJ -Sperre nicht erhalten, und es kann nicht in der Lage sein, den Thread A im synchronisierten (OBJ) {...} Code aufzuwecken Segment.
Wenn die Methode der obj.wait () zurückgibt, muss der Thread A die OBJ -Sperre erneut abrufen, um die Ausführung fortzusetzen.
Wenn Threads A1, A2, A3 in obj.wait () sind, nennt der Thread B obj.notify () nur einen der Threads A1, A2, A3 (welches durch JVM bestimmt wird).
Wenn Thread B obj.notifyAll () aufruft, kann er alle den wartenden Thread A1, A2, A3 aufwachen, aber der wartende Thread, um den nächsten Satz von obj.wait () weiter auszuführen, müssen Sie eine OBJ -Sperre erhalten. Daher haben Threads A1, A2, A3 nur eine Chance, Schlösser zu erhalten und weiter auszuführen.
Wenn Thread B obj.notify () oder obj.notifyall () aufruft, hält Thread B die OBJ -Sperre. Bis der Thread B den synchronisierten Codeblock beendet und die OBJ -Sperre freigeben, hat eine im Thread A1, A2, A3 die Möglichkeit, die Objektsperrung zu erhalten und weiter auszuführen.
Zum Beispiel Code
Die typische Codestruktur des Wartevorgangs des Threads lautet wie folgt:
public void test () löscht InterruptedException {synchronisiert (obj) {while (! Fortsetzung) {obj.wait ();}}}}}}}}}
Warum müssen sich Obj.wait () Operationen im Zyklus befinden? Es gibt mehrere Hauptgründe:
1. Ein Objektschloss kann verwendet werden, um mehrere Zustandsvariablen zu schützen. Beispielsweise sperrt ein bestimmtes Objekt OBJ, um die beiden Statusvariablen A und B. zu schützen, wenn die Bedingungen einer Behauptung nicht festgelegt sind, die Wartevorstellung erfolgt, wenn die Bedingung von B übersetzend ist, der Wartevorgang erfolgt in der Warteschlange. Wenn eine Operation einer Zustandsvariable A auftritt, wird die Notifyall -Operation auf OBJ aufgerufen, dann werden alle Threads in der Bedingung, die dem OBJ entspricht, erweckt. Für B wird zu diesem Zeitpunkt auch erweckt, sodass Sie recyceln müssen, ob der Zustand von B erfüllt ist, um erfüllt zu werden.
2. Die Bedingungen desselben Zustands mehrerer Threads werden geltend gemacht. Zum Beispiel ist die Szene, in der Elemente zur Warteschlange hinzugefügt werden, die aktuelle Warteschlange voll und mehrere Threads möchten Elemente hinzufügen, sodass sie alle sind. Zu diesem Zeitpunkt nahm ein anderer Thread ein Element aus der Warteschlange heraus und rief die Notifyall -Operation auf, um alle Threads aufzuwecken, aber nur ein Thread könnte der Warteschlange ein Element hinzufügen.
3.. Falsches Erwachen. Ohne benachrichtigt zu werden, Interrupt Orout, wurde der Thread automatisch geweckt. Obwohl diese Situation in der Praxis selten auftritt, kann diese Situation durch das Warten von Zyklus beseitigt werden.