wake-up-neo.com

Unterschied zwischen WAIT- und BLOCKED-Thread-Status

Was ist der Unterschied zwischen dem Thread-Status WAIT und dem Thread-Status BLOCKED?

Die Thread.State-Dokumentation :

Verstopft
In diesem Status befindet sich ein Thread, der blockiert ist und auf eine Monitorsperre wartet.

Warten
In diesem Status befindet sich ein Thread, der unendlich lange darauf wartet, dass ein anderer Thread eine bestimmte Aktion ausführt

erklärt mir den Unterschied nicht.

74
More Than Five

Ein Thread geht in den Wartezustand, sobald er wait() für ein Objekt aufruft. Dies wird als Waiting State ..__ bezeichnet. Wenn ein Thread den Wartezustand erreicht, muss er warten, bis ein anderer Thread notify() oder notifyAll() am Objekt vorhanden ist.

Sobald dieser Thread benachrichtigt wurde, kann er nicht mehr ausgeführt werden. Es kann sein, dass auch andere Threads benachrichtigt werden (mithilfe von notifyAll()) oder der erste Thread seine Arbeit noch nicht abgeschlossen hat. Er bleibt also blockiert, bis er seine Chance erhält. Dies wird als Blocked State bezeichnet.

Sobald andere Threads übrig sind und diese Thread-Chance besteht, wird der Status "Runable" (Runable) festgelegt. Danach kann die Arbeit basierend auf dem Threading-Mechanismus der JVM aufgenommen werden und der Status "Run" (Run) wird aktiviert.

54
Ankit Bansal

Der Unterschied ist relativ einfach.

Im BLOCKED-Status ist ein Thread im Begriff, einen synchronized-Block einzugeben, es läuft jedoch ein anderer Thread innerhalb eines synchronized-Blocks für dasselbe Objekt. Der erste Thread muss dann warten, bis der zweite Thread seinen Block beendet.

Im WAITING-Status wartet ein Thread auf ein Signal von einem anderen Thread. Dies geschieht normalerweise durch Aufruf von Object.wait() oder Thread.join(). Der Thread bleibt dann in diesem Zustand, bis ein anderer Thread Object.notify() aufruft oder stirbt.

68
Flavio

Der wichtige Unterschied zwischen den Zuständen "blockiert" und "wait" ist die Auswirkung auf den Scheduler. Ein Thread im gesperrten Zustand ist Teil eines Wartesets, das um eine Sperre kämpft. 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 es für die Ausführung von Threads gibt. 

Sobald sich ein Thread im Wartezustand befindet, wird die Belastung für das System minimiert, und der Scheduler muss sich nicht darum kümmern. Es wird inaktiv, bis es eine Benachrichtigung erhält. Abgesehen von der Tatsache, dass ein OS-Thread belegt ist, ist er völlig außer Betrieb.

Deshalb ist die Verwendung von notifyAll nicht ideal, da es eine Reihe von Threads verursacht, die zuvor glücklich inaktiv waren und das System nicht belastet, um geweckt zu werden. Die meisten von ihnen blockieren, bis sie die Sperre finden und den Zustand finden, in dem sie sich befinden Warten auf ist nicht wahr, und warten Sie ab. Es wäre wünschenswert, nur die Threads zu benachrichtigen, die die Chance haben, Fortschritte zu erzielen. 

(Durch die Verwendung von ReentrantLock anstelle von intrinsischen Sperren können Sie mehrere Bedingungen für eine Sperre festlegen. So können Sie sicherstellen, dass der gemeldete Thread auf eine bestimmte Bedingung wartet, um den Benachrichtigungsfehler zu vermeiden, falls ein Thread benachrichtigt wird etwas, woran es nicht handeln kann.)

Vereinfachte Perspektive für die Interpretation von Thread-Dumps:

  • WAIT- Ich warte darauf, etwas Arbeit zu bekommen, also bin ich jetzt im Leerlauf.
  • BLOCKIERT- Ich bin damit beschäftigt, die Arbeit zu erledigen, aber ein anderer Thread steht mir im Weg, also bin ich jetzt im Leerlauf.
  • RUNNABLE... (Native Method) - Ich habe RUN einige native Codes aufgerufen (die noch nicht abgeschlossen sind). Was die JVM angeht, sind Sie RUNNABLE und können nicht geben irgendwelche weiteren Informationen. Ein typisches Beispiel wäre eine native Socket-Listener-Methode, die in C codiert ist und tatsächlich darauf wartet, dass kein Datenverkehr ankommt, also bin ich momentan im Leerlauf. In dieser Situation kann dies als eine besondere Art von WAIT angesehen werden, da wir eigentlich gar nicht RUNNING (kein CPU-Burn) laufen, aber Sie müssten einen OS-Thread-Dump anstelle eines Java-Thread-Dumps verwenden, um dies zu sehen.
7
oldguy

Blockiert: Ihr Thread befindet sich im laufenden Zustand des Threads und versucht, eine Objektsperre zu erhalten. Warten- Ihr Thread befindet sich im Wartezustand des Threads und wartet darauf, dass das Benachrichtigungssignal im Run-Zustand des Threads erscheint.

1
Prakash Bisht

siehe dieses Beispiel:

demonstration der Threadzustände.

/*NEW- thread object created, but not started.
RUNNABLE- thread is executing.
BLOCKED- waiting for monitor after calling wait() method.
WAITING- when wait() if called & waiting for notify() to be called.
  Also when join() is called.
TIMED_WAITING- when below methods are called:
 Thread.sleep
 Object.wait with timeout
 Thread.join with timeout
TERMINATED- thread returned from run() method.*/
public class ThreadBlockingState{

public static void main(String[] args) throws InterruptedException {
    Object obj= new Object();
    Object obj2 = new Object();
    Thread3 t3 = new Thread3(obj,obj2);
    Thread.sleep(1000);
    System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+
            ",when Wait() is called & waiting for notify() to be called.");
    Thread4 t4 = new Thread4(obj,obj2);
    Thread.sleep(3000);
    System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+",After calling Wait() & waiting for monitor of obj2.");
    System.out.println("nm:"+t4.getName()+",state:"+t4.getState().toString()+",when sleep() is called.");
}

}
class Thread3 extends Thread{
Object obj,obj2;
int cnt;
Thread3(Object obj,Object obj2){
    this.obj = obj;
    this.obj2 = obj2;
    this.start();
}

@Override
public void run() {
    super.run();
    synchronized (obj) {
        try {
            System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before Wait().");
            obj.wait();             
            System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After Wait().");
            synchronized (obj2) {
                cnt++;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
}
class Thread4 extends Thread{
Object obj,obj2;
Thread4(Object obj,Object obj2){
    this.obj = obj;
    this.obj2 = obj2;
    this.start();
}

@Override
public void run() {
    super.run();
    synchronized (obj) {
        System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before notify().");
        obj.notify();
        System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After notify().");
    }
    synchronized (obj2) {
        try {
            Thread.sleep(15000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
}
0
murali