2016-04-23 6 views
1

私のコードが正しく動作しない理由を理解できません。私は最初のスレッドが2番目のスレッドが共有のブール値「喜び」をtrueに設定してから、最初のスレッドが「喜びが達成されました!」というメッセージを4秒間待つことを期待します。保護されたブロックを稼働させようとしています

私は、コードを実行すると、私はこの出力を得る:

"いいえ喜びしかし..."

"届出事業喜び"

そして、それがフリーズしてdoesnの」に続行する。私の理解が正しい場合、notifyJoy()メソッドから呼び出されたnotifyAll()メソッドはwait()からt1を起動し、共有静的ブール変数joyがtrueになっているので、 "Joyは達成されました!コンソールに印刷する必要があります。

私はオラクルの「Javaチュートリアル」の第13章から作業しています。具体的なセクションへのリンクはJava Tutorial Websiteです。私は彼らが持っているものから脱して少しの例を挙げているが、私が間違っていることを理解できないようだ。どんな助けもありがとう。ここに私のコードの完全なコピーはご参考用です:

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(); 
    } 
} 

答えて

3

あなたは異なるモニタ上wait()notifyAll()を呼び出して、より具体的には、二つの異なるJoyRiderインスタンスの組み込みのモニターにされています。

専用のロック・オブジェクトを導入した場合:

private static final Object LOCK = new Object();

とあなたのrun()方法を少し変更します。

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!"); 
    } 
} 

を正しい順序ですべての期待プリントを見ることができるはずです。

3

については、the docsをご覧ください。

待機中のすべてのスレッドをウェイクアップこのオブジェクトのモニタ。

強調鉱山。 2つのJoyRiderj1およびj2があります。それぞれはwaitを呼び出します。したがって、notifyAllを呼び出すと、そのインスタンスで待機中のスレッドのみに通知されます(つまり、j1j1で待機中のスレッドにのみ通知し、j2j2で待機するスレッドに通知します)。

代わりに静的オブジェクトを同期させてロックすることでこれを修正できます。したがって、private static final Object LOCK = new Object();を追加し、両方の方法をsynchronize(LOCK)に変更し、thisではなくLOCKnotifyAllwaitを呼び出してください。

関連する問題