読者です 読者をやめる 読者になる 読者になる

Javaのwait()、notify()、notifyAll()を試す

Javaのwait()、notify()、notifyAll()を試してみたメモです。

Javaのスレッドの勉強のためwait()、notify()、notifyAll()を試してみました。

Object (Java Platform SE 8)
wait()、notify()、notifyAll()はObjectクラスのメソッドです。

wait()

wait()を呼び出すと現在のスレッドが待機します。

wait()を呼び出したスレッドはそのオブジェクトのウェイトセットに入ります。
ウェイトセットに入ったスレッドは、そのオブジェクトのnotify()またはnotifyAll()が呼び出されるまで待機します。

try {
    wait();
} catch (InterruptedException e) {
    e.printStackTrace();
}

notify()

notify()を呼び出すとそのオブジェクトのウェイトセットにあるスレッドが1つ再開します。
複数のスレッドが待機している場合は、そのうちのどれか1つが再開します。

下記のようにwait()するメソッドと、notify()するメソッドを用意。

WaitAndNotify.java

public class WaitAndNotify {
    synchronized void threadWait() {
        System.out.println("wait!");
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("unlocked!");
    }

    synchronized void threadNotify() {
        notify();
        System.out.println("notified!");
    }
}

テスト。
wait()を呼び出すスレッドと、notify()を呼び出すスレッドを生成し、実行。

WaitAndNotifyMain.java

public class WaitAndNotifyMain {
    public static void main(String[] args) throws InterruptedException {
        WaitAndNotify waitAndNotify = new WaitAndNotify();

        Runnable taskWait = waitAndNotify::threadWait;
        new Thread(taskWait).start();

        // 3,000msec待機
        Thread.sleep(3000);

        Runnable taskNotify = waitAndNotify::threadNotify;
        new Thread(taskNotify).start();
    }
}

はじめにwait!が表示され、3秒後にnotified!が表示され、
スレッドが再開されunlocked!が表示される。

wait!
notified!
unlocked!

notifyAll()

notifyAll()を呼び出すと、そのオブジェクトのウェイトセットにある全てのスレッドが再開します。

下記のようにwait()するメソッドと、notifyAll()するメソッドを用意。

WaitAndNotifyAll.java

public class WaitAndNotifyAll {
    synchronized void threadWait() {
        System.out.println(Thread.currentThread().getName() + ": wait!");
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + ": unlocked!");
    }

    synchronized void threadNotifyAll() {
        notifyAll();
        System.out.println("notified ALL!");
    }
}

テスト。
wait()を呼び出すスレッド4つと、notifyAll()を呼び出すスレッドを生成し、実行。

WaitAndNotifyAllMain.java

public class WaitAndNotifyAllMain {
    public static void main(String[] args) throws InterruptedException {
        WaitAndNotifyAll waitAndNotifyAll = new WaitAndNotifyAll();

        Runnable taskWait = waitAndNotifyAll::threadWait;
        new Thread(taskWait).start();
        new Thread(taskWait).start();
        new Thread(taskWait).start();
        new Thread(taskWait).start();

        // 3,000msec待機
        Thread.sleep(3000);

        Runnable taskNotifyAll = waitAndNotifyAll::threadNotifyAll;
        new Thread(taskNotifyAll).start();
    }
}

はじめに4つのスレッドでwait!が表示され、3秒後にnotified ALL!が表示され
すべてのスレッドが再開されunlocked!が表示される。

Thread-1: wait!
Thread-2: wait!
Thread-3: wait!
Thread-0: wait!
notified ALL!
Thread-0: unlocked!
Thread-3: unlocked!
Thread-2: unlocked!
Thread-1: unlocked!

こんなとこです。

github.com