////////////////////////////////////////////////////////////////////////////////
//  << j551ajava >>
//
//  スレッド(5):スレッド間通信(waitメソッド、notifyメソッドの組合せ)
//
//  1つのスレッドがwaitメソッドを実行し一時停止する。
//  mainメソッドからnotifyメソッドを使って、このメソッドの実行を再開する。
//    スレッド間通信のためにひとつのオブジェクトを使う。
//  このために旗クラスを定義する。
//
//  (1)旗クラスの定義。
//  (2)スレッド(Thread1)の定義。
//  (3)現在のスレッドを表示するメソッドの定義。
//  (4)現在のスレッドを表示するメソッドの定義。
//  (5)スレッドの作成。
//  (6)スレッドの実行。
//  (7)待機時間。
//  (8)現在のスレッドをすべて表示。
//  (9)一時停止中のスレッドを再開。
//
////////////////////////////////////////////////////////////////////////////////

//(1)
class Flag {
  synchronized void WAIT() { 
    try {
      System.out.println("スレッド(" + Thread.currentThread().getName() + ") wait 開始");
      wait();
      System.out.println("スレッド(" + Thread.currentThread().getName() + ") wait 終了");
    } catch( InterruptedException e ) { }
  }
  synchronized void NOTIFY() {
    System.out.println("スレッド(" + Thread.currentThread().getName() + ") notify 開始");
    notify();
    System.out.println("スレッド(" + Thread.currentThread().getName() + ") notify 終了");
  }
}

//(2)
class Thread1 extends Thread { 
  Flag f;
  Thread1(Flag f) { // コンストラクタ。
    this.f = f; 
  }
  public void run() {
    System.out.println("スレッド(" + this.getName() + ") 開始");
    f.WAIT();
    System.out.println("スレッド(" + this.getName() + ") 終了");
  }
}

class j551a {
  //(3)
  static void show() {
    int n = Thread.activeCount();
    Thread th[] = new Thread[n];
    int m = Thread.enumerate(th);
    System.out.println("  [現在のスレッド表示開始]");
    for( int i=0; i<m; i++ ) {
      System.out.println("  " + i + "番目のスレッド:" + th[i].getName());
    }
    System.out.println("  [現在のスレッド表示終了]");
  }

  public static void main(String args[]) {

    Flag f = new Flag(); //(4)

    Thread1 th = new Thread1(f); //(5) 

    th.start(); //(6)

    try {
      Thread.sleep(3000); //(7)
    } catch ( InterruptedException e ) { } 

    show(); //(8)

    f.NOTIFY(); //(9)

    try {
      Thread.sleep(3000); //(7)
    } catch ( InterruptedException e ) { } 

     show(); //(8)

  }

}
実行結果
% javac j551a.java
% java j551a 
スレッド(Thread-0) 開始
スレッド(Thread-0) wait 開始
  [現在のスレッド表示開始]
  0番目のスレッド:main
  1番目のスレッド:Thread-0
  [現在のスレッド表示終了]
スレッド(main) notify 開始
スレッド(main) notify 終了
スレッド(Thread-0) wait 終了
スレッド(Thread-0) 終了
  [現在のスレッド表示開始]
  0番目のスレッド:main
  [現在のスレッド表示終了]