ホームページ  >  記事  >  Java  >  Java の sleep メソッドと wait メソッドの違いは何ですか?

Java の sleep メソッドと wait メソッドの違いは何ですか?

WBOY
WBOY転載
2023-05-06 09:52:061201ブラウズ

    1. sleep メソッドと wait メソッドの違い

    • 根本的な違い: sleep は Thread クラスのメソッドであり、すぐには入力できません 実行状態では、wait は Object クラスのメソッドです。オブジェクトが wait メソッドを呼び出したら、notify() メソッドと NoticeAll() メソッドを使用してプロセスを起動する必要があります

    • 同期ロックを解放します: sleep CPU は解放されますが、sleep は同期ロック リソースを解放しません。wait は同期ロック リソースを解放します

    • 使用範囲: sleep は可能ですどこでも使用できますが、wait は同期でのみ使用できます。

    • メソッドまたはコード ブロックで例外処理を使用します。sleep は例外をキャッチする必要がありますが、wait は例外をキャッチする必要はありません

    2. wait メソッド

    • 現在コードを実行しているスレッドを待機させます (スレッドを待機キューに入れます)

    • 現在のロックを解放します

    • 特定の条件が満たされると起動され、再度ロックの取得を試みます。

    • ##待機する必要があります。 synchronized とともに使用されます。synchronized なしで wait を使用すると、直接例外がスローされます。

    wait メソッドの使用

    wait メソッド

    /**
     * wait的使用
     */
    public class WaitDemo1 {
        public static void main(String[] args) {
            Object lock = new Object();
            Thread t1 = new Thread(() -> {
                System.out.println("线程1开始执行");
                try {
                    synchronized (lock) {
                        System.out.println("线程1调用wait方法....");
                        // 无限期的等待状态
                        lock.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程1执行完成");
            }, "线程1");
            t1.start();
        }
    }

    パラメータとパラメータなしの待機スレッド

    /**
     * 有参wait线程和无参wait线程
     */
    public class WaitDemo2 {
        public static void main(String[] args) {
            Object lock1 = new Object();
            Object lock2 = new Object();
            Thread t1 = new Thread(()->{
                System.out.println("线程1开始执行");
                synchronized (lock1){
                    try {
                        lock1.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程1执行完成");
                }
            },"无参wait线程");
            t1.start();
            Thread t2 = new Thread(()->{
                System.out.println("线程2开始执行");
                synchronized (lock2){
                    try {
                        lock2.wait(60*60*1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程2执行完成");
                }
            },"有参wait线程");
            t2.start();
        }
    }

    待機終了待機条件

    ①他のスレッドがオブジェクトのnotifyメソッドを呼び出す。

    ②待機待機時間がタイムアウトする(待機メソッドはバージョンを提供する)

    ③他のスレッドが待機中のスレッドの中断されたメソッドを呼び出し、待機によって InterruptedException 例外がスローされます。

    3. Notice メソッドと NotifyAll メソッド

    notify メソッドは、特定の待機中のスレッドのみを起動します

    1. メソッド Notice() は、同期メソッドまたは同期ブロックでも呼び出す必要があります。このメソッドは、他のスレッドに通知するために使用されますオブジェクトのオブジェクト ロックを待機している可能性があります

    2. 待機しているスレッドが複数ある場合は、待機状態のスレッドをランダムに選択します

    3. ##Afterこのメソッドのスレッドは、プログラムの実行を終了します。つまり、オブジェクト ロックは、メソッドを終了した後に解放されます。同期されたコード ブロック。
    4. notify メソッドを使用すると、
    /**
     * wait的使用, 如果有多个线程等待,随机挑选一个wait状态的线程
     */
    public class WaitNotifyDemo {
        public static void main(String[] args) {
            Object lock1 = new Object();
            Object lock2 = new Object();
            Thread t1 = new Thread(()->{
                System.out.println("线程1开始执行");
                try {
                    synchronized (lock1) {
                        System.out.println("线程1调用wait方法");
                        lock1.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程1执行完成");
            },"线程1");
            Thread t2 = new Thread(()->{
                System.out.println("线程2开始执行");
                try {
                    synchronized (lock1) {
                        System.out.println("线程2调用wait方法");
                        lock1.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程2执行完成");
            },"线程2");
            t1.start();
            t2.start();
            // 唤醒 lock1 对象上休眠的线程的(随机唤醒一个)
            Thread t3 = new Thread(()->{
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程3开始执行");
                synchronized (lock1){
                    //发出唤醒通知
                    System.out.println("执行了唤醒");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },"线程3");
            t3.start();
        }
    }

    notifyAll メソッドを一度に起動できます。待機中のスレッド

    notifyAll メソッドの使用法

    /**
     * notifyAll-唤醒所有线程
     */
    public class WaitNotifyAll {
        public static void main(String[] args) {
            Object lock = new Object();
    
            new Thread(() -> {
                System.out.println("线程1:开始执行");
                synchronized (lock) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程1:执行完成");
                }
            }, "无参wait线程").start();
    
            new Thread(() -> {
                synchronized (lock) {
                    System.out.println("线程2:开始执行 |" + LocalDateTime.now());
                    try {
                        lock.wait(60 * 60 * 60 * 1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程2:执行完成 | " + LocalDateTime.now());
                }
            }, "有参wait线程").start();
    
            new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock) {
                    System.out.println("唤醒所有线程");
                    lock.notifyAll();
                }
            }).start();
        }
    }

    notify メソッドとnotifyAll メソッドの違い

      notify を呼び出すと、待機中のスレッドが 1 つだけ起動されます。また、どのスレッドが起動されるかは保証されません。状況によって異なります。スレッドスケジューラ上で。
    1. notifyAll メソッドを呼び出すと、ロックを待機しているすべてのスレッドが起動されますが、残りのコードが実行される前に、起動されたすべてのスレッドがロックをめぐって競合するため、ループ内で複数のスレッドが起動している場合、ロックを取得するスレッドが最初に実行され、待機条件がリセットされる可能性があるため、後続のスレッドは強制的に待機することになります。
    2. つまり、notify と NoticeAll の主な違いは、notify() は 1 つのスレッドのみを起動するのに対し、notifyAll メソッドはすべてのスレッドを起動することです。

    以上がJava の sleep メソッドと wait メソッドの違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。