2016-09-15 45 views
-2

2つのスレッドが同時に実行されているプログラムを作成しようとしています。 1つはプリントジャック、もう1つはジョーンズです。期待される出力は: ジャックジョーンズジャックジョーンズなどです。しかし私はのnotifyAll()を呼び出しながら問題に直面しています。誰が問題を教えてくれますか?2つの異なる文字列を2つのスレッドで順に印刷する

例外

Starting thread 
Jack Jones Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalMonitorStateException 
at java.lang.Object.notifyAll(Native Method) 
at JonesThread.printJones(JonesThread.java:32) 
at JonesThread.run(JonesThread.java:14) 
java.lang.IllegalMonitorStateException 
at java.lang.Object.notifyAll(Native Method) 
at JackThread.printJack(JackThread.java:36) 
at JackThread.run(JackThread.java:15) 

ジャックスレッド

import java.util.concurrent.atomic.AtomicBoolean; 

public class JackThread extends Thread { 

AtomicBoolean i; 

public JackThread(AtomicBoolean i2) { 

    this.i = i2; 
} 

public void run() { 
    while (true) { 
     try { 
      printJack(); 
      Thread.sleep(10000); 

     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

private void printJack() throws InterruptedException { 

    synchronized (i) { 
     while (i.get()) { 
      { 
       wait(); 
      } 
     } 

     System.out.print("Jack "); 
     i.set(true); 
     notifyAll(); 

    } 
} 
} 

ジョーンズスレッド

import java.util.concurrent.atomic.AtomicBoolean; 

public class JonesThread extends Thread { 

AtomicBoolean i; 

public JonesThread(AtomicBoolean i2) { 
    this.i = i2; 
} 

public void run() { 
    while (true) { 
     try { 
      printJones(); 

      Thread.sleep(500); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

private void printJones() throws InterruptedException { 
    synchronized (i) { 
     while (!i.get()) { 
      wait(); 
     } 

     System.out.print("Jones "); 
     i.set(false); 
     notifyAll(); 
    } 
} 
} 

メインプログラム

import java.util.concurrent.atomic.AtomicBoolean; 

public class ThreadMain { 
public static void main(String args[]) { 
    AtomicBoolean i = new AtomicBoolean(false); 
    System.out.println("Starting thread"); 
    JackThread t1 = new JackThread(i); // Will give chance to Print Jack first 
    JonesThread t2 = new JonesThread(i);// Jones will follow Jack 

    t1.start(); 
    t2.start(); 
} 
} 

答えて

2

waitの定義は、あなたが

someObject.wait(); 

を言えば誰かがsomeObjectのモニターを通知するまでスレッドが待機するということです。別のスレッドが呼び出すことでそれを行うことができます

someObject.notify(); // or notifyAll 

スレッドは同じオブジェクトを使用して調整する必要があります。あなたは、オブジェクトを指定していないので、あなたのwait()は、誰かが自分自身を通知するためJackThreadオブジェクトが待っている、

ある
this.wait(); 

に相当します。しかし、誰もJackThreadオブジェクトに通知していません。あなたのJonesThreadnotifyAll()を呼び出すと、それはとても

this.notifyAll(); 

それは自分自身を通知しています、すなわちJonesThreadオブジェクトと同じです。だから、基本的に、あなたの2つのスレッドは、自分自身に話していて、お互いに話していません

あなたは両方のスレッドには知られているオブジェクトとしてiを設定しているので、あなたがあなたのwaitnotifyのためにそれを使用することができ、すなわちi.wait()i.notifyAll()のように見えます。 免責事項:私はそれをテストしていません。

+0

ありがとう、私は試して、テストした、それは働いた。 – Incredible

関連する問題