Was ist der Unterschied zwischen dem Thread-Status WAIT und dem Thread-Status BLOCKED?
Die Thread.State-Dokumentation :
Blockiert
Ein Thread, der blockiert ist und auf eine Monitorsperre wartet, befindet sich in diesem Status.Warten
Ein Thread, der auf unbestimmte Zeit darauf wartet, dass ein anderer Thread eine bestimmte Aktion ausführt, befindet sich in diesem Status
erklärt mir den Unterschied nicht.
java
multithreading
block
wait
Mehr als fünf
quelle
quelle
Antworten:
Ein Thread wartet, sobald er
wait()
ein Objekt aufruft . Dies wird als Wartezustand bezeichnet . Sobald ein Thread den Wartezustand erreicht, muss er warten, bis ein anderer Threadnotify()
odernotifyAll()
das Objekt aufgerufen wird.Sobald dieser Thread benachrichtigt wurde, kann er nicht mehr ausgeführt werden. Es kann sein, dass andere Threads ebenfalls benachrichtigt werden (using
notifyAll()
) oder der erste Thread seine Arbeit noch nicht beendet hat, sodass er immer noch blockiert ist, bis er seine Chance bekommt. Dies wird als blockierter Zustand bezeichnet. Ein blockierter Status tritt immer dann auf, wenn ein Thread versucht, eine Sperre für ein Objekt zu erlangen, und ein anderer Thread die Sperre bereits hält.Sobald andere Threads abgereist sind und diese Thread-Chance besteht, wechselt sie in den Status "Ausführbar". Danach ist sie berechtigt, Arbeiten basierend auf dem JVM-Threading-Mechanismus aufzunehmen, und wechselt in den Status "Ausführen".
quelle
Der Unterschied ist relativ einfach.
In diesem
BLOCKED
Zustand ist ein Thread im Begriff, einensynchronized
Block einzugeben , aber es wird derzeit ein anderer Thread in einemsynchronized
Block für dasselbe Objekt ausgeführt. Der erste Thread muss dann warten, bis der zweite Thread seinen Block verlassen hat.In diesem
WAITING
Zustand wartet ein Thread auf ein Signal von einem anderen Thread. Dies geschieht normalerweise durch Aufrufen vonObject.wait()
oderThread.join()
. Der Thread bleibt dann in diesem Zustand, bis ein anderer Thread aufruftObject.notify()
oder stirbt.quelle
Object.wait()
direkt, aber Sie landen imWAITING
Status, indem Sie auch die übergeordneten Parallelitätskonstrukte verwenden - wie Sperren, Blockierungswarteschlangen usw. Im Großen und Ganzen, wenn zwei Threads koordiniert werden müssen.RUNNING
Status.Thread.State
heißt es: "... Diese Zustände sind Zustände der virtuellen Maschine, die keine Betriebssystem-Thread-Zustände widerspiegeln." Mit anderen Worten, die JVM kümmert sich nicht um den Unterschied zwischen einem Thread, in dem Java-Code ausgeführt wird, einem Thread, der auf die Rückkehr eines Systemaufrufs wartet, oder einem Thread, der auf eine Zeitscheibe wartet. Das ist alles genauRUNNABLE
so, wie es die JVM betrifft.WAITING
Status wechselt, zuerst in denBLOCKED
Status wechseln muss, bis er die Sperre für das Objekt erhalten kann, auf das er gewartet hat.Der wichtige Unterschied zwischen dem blockierten und dem Wartezustand ist die Auswirkung auf den Scheduler. Ein Thread in einem blockierten Zustand kämpft um eine Sperre. Dieser Thread zählt immer noch als etwas, das der Scheduler warten muss, und wird möglicherweise in die Entscheidungen des Schedulers einbezogen, wie viel Zeit für laufende Threads zur Verfügung steht (damit die Threads, die die Sperre blockieren, eine Chance erhalten).
Sobald sich ein Thread im Wartezustand befindet, wird die Belastung des Systems minimiert, und der Scheduler muss sich keine Sorgen mehr machen. Es wird ruhend, bis es eine Benachrichtigung erhält. Abgesehen von der Tatsache, dass ein Betriebssystem-Thread besetzt bleibt, ist es völlig aus dem Spiel.
Aus diesem Grund ist die Verwendung von notifyAll weniger als ideal. Es führt dazu, dass eine Reihe von Threads, die zuvor glücklich ruhten und das System nicht belasteten, aufgeweckt wurden. Die meisten von ihnen blockieren, bis sie die Sperre erlangen und den Zustand finden, in dem sie sich befinden Warten ist nicht wahr, und kehren Sie zum Warten zurück. Es wäre vorzuziehen, nur diejenigen Threads zu benachrichtigen, die eine Chance auf Fortschritte haben.
(Wenn Sie ReentrantLock anstelle von intrinsischen Sperren verwenden, können Sie mehrere Bedingungen für eine Sperre festlegen, sodass Sie sicherstellen können, dass der benachrichtigte Thread auf eine bestimmte Bedingung wartet, und den Fehler bei der Benachrichtigung über verlorene Benachrichtigungen vermeiden, wenn ein Thread benachrichtigt wird etwas, auf das es nicht einwirken kann.)
quelle
Vereinfachte Perspektive für die Interpretation von Thread-Dumps:
quelle
RUNNABLE
ist nicht ganz richtig. Es könnte sich in der Java-Ausführungswarteschlange befinden, aber nicht ausgeführt werden, oder es könnte Java-Code ausführen. Es muss nicht in die Heimat rufen.Blockiert - Ihr Thread befindet sich im ausführbaren Zustand des Thread-Lebenszyklus und versucht, eine Objektsperre zu erhalten. Warten - Ihr Thread befindet sich im Wartezustand des Thread-Lebenszyklus und wartet darauf, dass das Benachrichtigungssignal in den ausführbaren Zustand des Threads gelangt.
quelle
siehe dieses Beispiel:
Demonstration von Thread-Zuständen.
quelle