Java Thread wait notify

Objectクラスの同期制御

  • final void wait()
    • notify()またはnotifyAll()が呼び出されるまでスレッドを待機させます。
    • 同期領域でロックを解放し、Wait-Set領域(共有オブジェクトごとに存在)へ移動させます。
  • final void wait(long timeout)
    • wait()のタイムアウト版です。
  • final void notify()
    • このオブジェクトで待機中のthreadを1つ再開します。再開対象は選択できません。
    • Wait-Set領域にあるスレッドを起こして実行できるようにします。
    • notify()は任意のスレッドを起こすため、意図したスレッド以外を起こす場合もあります。
  • final void notifyAll()
    • このオブジェクトで待機中のすべてのthreadを再開します。
    • notifyAll()はWait-Setにあるスレッドをすべて起こします。
  • wait、notify、notifyAllはいずれも同期領域でのみ実行できます。
  • Objectクラスで提供されるメソッドです。
package com.devkuma.basic.thread.wait;

public class ThreadA extends Thread {
    // このスレッドが実行されると、自分自身のモニタリングロックを取得します。
    // 5回繰り返し、0.5秒ずつ休みながらtotalに値を累積します。
    // その後notify()メソッドを呼び出し、waitしているスレッドを起こします。
    int total;

    @Override
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(i + "를 더합니다.");
                total += i;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            notify();
        }
    }

    public static void main(String[] args) {
        // スレッドAを生成した後、startします。
        // 該当スレッドが実行されると、runメソッド内で自身のモニタリングロックを取得します。
        ThreadA a = new ThreadA();
        a.start();

        // aに対して同期ブロックを設定します。
        // mainスレッドが下のブロックをThreadAより先に実行した場合、waitしながらモニタリングロックを解放して待機します。
        synchronized (a) {
            try {
                // a.wait()メソッドを呼び出します。
                // メインスレッドは停止します。
                // ThreadAが5回値を加算した後notifyを呼び出すと、waitから起こされます。
                System.out.println("b가 완료될때까지 기다립니다.");
                a.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 起こされた後、結果を出力します。
            System.out.println("Total is: " + a.total);
        }
    }
}