2016-04-09 6 views
4

Ich habe Klasse Run. Ist einfach, nur druckt, schläft und druckt dann;Warum Objekt nicht gesperrt ist, während der Thread im Runnable-Status ist?

public class Run implements Runnable { 

    @Override 
    public void run() { 
     System.out.println("START RUN"); 
     try { 
      Thread.sleep(50); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("FINISH RUN"); 
    } 
} 

Ok jetzt schreibe ich test;

public static synchronized void main(String[] args) throws InterruptedException { 

     Run r = new Run(); 
     Thread t = new Thread(r, "TEST"); 
     t.start(); 

     // EXECYTE THE CODE WHULE THREAD "TEST" IS RUNNABLE 
     synchronized (t) { 
      System.out.println(t.getState()); 
      t.wait(); 
     } 
     System.out.println("Y"); 

     // SLEEP THREAD "TEST" TO BE EXECUTED DURING THE TIME 
     Thread.sleep(100); 
     synchronized (t) { 
      System.out.println(t.getState()); 
      t.wait(); 
     } 
     System.out.println("Y2"); 
    } 

Frage 1: Während thread "TEST" ausführt, ich versuche() zu warten. In diesem Moment lautet der Thread-Status "RUNNABLE". Wegen dieses Status ist es nicht warten, verstehe ich nicht warum? Wenn der Status "TERMINATED" oder "NEW" lautet, funktioniert wait(); Wenn ich t.start() entferne, ist der Thread-Status "NEW", also funktioniert auch wait. Kannst du mir sagen, was passiert?

OUTPUT:

START RUN 
RUNNABLE 
FINISH RUN 
Y 
TERMINATED` 
+0

Schnelle Frage: was denkst du 't.wait()' tut? – biziclop

+0

Dies zeigt nur den Status an, wenn der Thread startet. 'Thread.sleep' sperrt nichts. –

+0

Bewirkt, dass der aktuelle Thread wartet, bis ein anderer Thread notify oder notifyAll aufruft. Wenn t.wait() ausgeführt wird, schläft der Thread zum einen, sodass er nicht wartet. aber nachdem der Thread ausgeführt wird, wird er gehängt – grep

Antwort

10

Dies ist eher schlecht dokumentiert. Die Javadoc- von Thread#join(long) heißt

als Thread beendet die this.notifyAll Methode aufgerufen wird. Es wird empfohlen, dass Anwendungen wait, notify oder notifyAll auf Thread Instanzen nicht verwenden.

Es ist speziell sagen, nicht tun, was Sie gerade tun. Das heißt, synchronized auf einem Thread Objekt und rufen wait auf das gleiche Objekt.

synchronized (t) { 
    System.out.println(t.getState()); 
    t.wait(); 
} 

In der aktuellen Ausführung Ihres Codes. Ihr Haupt-Thread erreicht den obigen Aufruf t.wait(), während Ihr TEST Thread schläft. TEST dann wacht auf und beendet. Wenn es beendet wird, ruft es notifyAll auf, wacht Ihren Hauptfaden von dem t.wait() auf.

Wenn Ihr Haupt-Thread dann die zweite t.wait() erreicht, ist nichts mehr in Ihrem Programm, um es aufzuwecken, also hängt Ihr Programm einfach.


All dies zu sagen: nicht für etwasThread Objekt Monitore verwenden.

+0

Und nur um klar zu sein, mit "empfohlen" meinen sie "mach es nie, mach es nie". :) Wirklich nicht. Tu es einfach nicht. – biziclop

+0

Ich verstehe nicht; :(Wenn Thread "TEST" in diesem Moment schläft t.wait() aufgerufen wird und - es hängt nicht. Ich verstehe nicht warum. Wenn Thread beendet ist oder neu es hungs. – grep

+0

Wenn es beendet ist oder neu (nicht gestartet) Es wird nicht 'notifyAll' aufrufen, also wird nichts den Hauptthread vom ersten' t.wait() 'aufwecken. – Savior

Verwandte Themen