2016-04-23 8 views
1

Ich verstehe nicht, warum mein Code nicht richtig funktioniert. Ich erwarte, dass der erste Thread 4 Sekunden lang auf den zweiten Thread wartet, um eine geteilte boolesche "Freude" auf "wahr" zu setzen, damit der erste Thread "Joy wurde erreicht!"Versuche, geschützte Blöcke zum Arbeiten zu bringen

Wenn ich den Code ausführen, bekomme ich diese Ausgabe:

"No Joy doch ..."

"Mitteile Joy"

Dann friert es und doesn‘ t fahre fort. Wenn mein Verständnis korrekt ist, sollte die notifyAll() -Methode, die von meiner notifyJoy() -Methode aufgerufen wird, t1 von seinem wait() aufwecken, und dann, da die gemeinsame statische boolesche variable Freude nun wahr ist, "Joy wurde erreicht!" sollte auf der Konsole drucken.

Ich arbeite von Oracle "The Java Tutorial", Kapitel 13: Hier ist ein Link zu dem spezifischen Abschnitt: Java Tutorial Website. Ich gehe von dem, was sie haben, und mache ein kleines Beispiel, aber ich kann nicht herausfinden, was ich falsch mache. Jede Hilfe wäre willkommen. Hier ist eine vollständige Kopie meines Codes für Ihre Referenz:

public class JoyTime { 

    public static void main(String[] args) { 
     JoyRider j1 = new JoyRider(false); 
     JoyRider j2 = new JoyRider(true); 

     Thread t1 = new Thread(j1, "J1"); 
     Thread t2 = new Thread(j2, "J2"); 

     t1.start(); 

     try { 
      Thread.sleep(4000); 
     } 
     catch (InterruptedException e) {} 

     t2.start(); 
    } 
} 

class JoyRider implements Runnable { 

    private static boolean joy = false; 
    private boolean flag; 

    public JoyRider(boolean flag) { 
     this.flag = flag; 
    } 

    @Override 
    public void run() { 
     synchronized(this) { 
      if (flag) { 
       notifyJoy(); 
      } 
      else { 
       while (!joy) { 
        System.out.println("No Joy Yet..."); 
        try { 
         this.wait(); 
        } 
        catch (InterruptedException e) {} 
       } 
       System.out.println("Joy has been achieved!"); 
      } 
     } 
    } 

    public synchronized void notifyJoy() { 
     System.out.println("Notifying Joy"); 
     joy = true; 
     notifyAll(); 
    } 
} 

Antwort

3

Sie rufen wait() und notifyAll() auf verschiedenen Monitoren und insbesondere auf den eingebauten Überwachungen der beiden unterschiedlichen JoyRider Instanzen.

Wenn Sie einführen ein spezielles Sperrobjekt:

private static final Object LOCK = new Object();

und ändern Sie Ihre run() Methode ein wenig:

synchronized (LOCK) { 
    if (flag) { 
     System.out.println("Notifying Joy"); 
     JOY = true; 
     LOCK.notifyAll(); 
    } 
    else { 
     while (!JOY) { 
     System.out.println("No Joy Yet..."); 
     try { 
      LOCK.wait(); 
     } 
     catch (InterruptedException e) {} 
     } 
     System.out.println("Joy has been achieved!"); 
    } 
} 

Sie sollten in der Lage sein, alle erwarteten Drucke in der richtigen Reihenfolge zu sehen .

3

Beginnen Sie mit Blick auf the docs für notifyAll.

Wacht alle Threads auf, die auf dieses Objekts Monitor warten.

Schwerpunkt meiner. Sie haben zwei JoyRider s, j1 und j2. Jeder von ihnen ruft wait auf sich. Wenn Sie also notifyAll anrufen, benachrichtigen Sie nur die Threads, die auf diese Instanz warten (dh. benachrichtigt nur Threads, die auf j1 warten, und j2 benachrichtigt nur Threads, die auf j2 warten).

Sie können dies beheben, indem Sie stattdessen ein statisches Objekt synchronisieren und sperren. Fügen Sie also private static final Object LOCK = new Object(); hinzu, lassen Sie beide Methoden auf synchronize(LOCK) ändern, und rufen Sie notifyAll und wait unter LOCK anstelle von this an.

Verwandte Themen