Javaのスレッド制御におけるsleepとwaitの挙動の違い

Thread.sleepによる一時停止

Thread.sleep()は、現在実行中のスレッドを指定された時間だけ一時停止させる静的メソッドです。このメソッドの大きな特徴は、休眠中であってもオブジェクトのロック(モニター)を解放しない点にあります。そのため、同期的な処理の中で一時的に処理を遅延させたい場合や、単純なタイミング調整に利用されるのが一般的です。

以下の例では、別のスレッドを作成し、その中で処理を3秒間一時停止させています。

public class SleepDemo {
    public static void main(String[] args) {
        Thread taskThread = new Thread(() -> {
            System.out.println("処理を開始しました。");
            try {
                // 処理を3秒間一時停止
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.err.println("スレッドが中断されました。");
            }
            System.out.println("処理が完了しました。");
        });
        
        taskThread.start();
    }
}

Object.waitによる待機と同期

wait()メソッドはjava.lang.Objectクラスで定義されており、スレッド間の協調的な動作を実現するために使用されます。このメソッドを呼び出すと、現在のスレッドは待機状態へ移行し、同時に確保していたオブジェクトのロックを解放します。他のスレッドが同じオブジェクトに対してnotify()またはnotifyAll()を呼び出すことで、待機中のスレッドは再開の機会を得ることができます。なお、このメソッドを使用する際は、必ずブロック内で呼び出す必要があります。

以下の例では、共有のロックオブジェクトを使用して、あるスレッドがもう一方のスレッドからの通知を待つ様子を示しています。

public class WaitNotifyDemo {
    private static final Object mutex = new Object();

    public static void main(String[] args) {
        Thread waitingThread = new Thread(() -> {
            synchronized (mutex) {
                try {
                    System.out.println("スレッドA: ロックを取得し、通知を待機します。");
                    // ロックを解放して待機状態へ
                    mutex.wait();
                    System.out.println("スレッドA: 通知を受け取り、処理を再開しました。");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread notifyingThread = new Thread(() -> {
            synchronized (mutex) {
                System.out.println("スレッドB: ロックを取得し、通知を送信します。");
                // 待機中のスレッドを1つだけ唤醒させる
                mutex.notify();
            }
        });

        waitingThread.start();
        notifyingThread.start();
    }
}

このコードの動作順序は以下の通りです。まずwaitingThreadがロックを取得してwait()を呼び出し、ロックを解放して待機します。その後、notifyingThreadがロックを取得し、notify()を呼び出して待機中のスレッドに終了を通知します。これにより、waitingThreadは処理を続行できるようになります。

タグ: Java スレッド 同期 マルチスレッド 並行処理

6月13日 21:23 投稿