Home  >  Article  >  Java  >  What is the difference between sleep and wait methods in Java?

What is the difference between sleep and wait methods in Java?

WBOY
WBOYforward
2023-05-06 09:52:061210browse

    1. The difference between sleep and wait methods

    • The fundamental difference: sleep is a method in the Thread class and will not be entered immediately In the running state, wait is a method in the Object class. Once an object calls the wait method, the notify() and notifyAll() methods must be used to wake up the process

    • Release the synchronization lock: sleep Will release the cpu, but sleep will not release the synchronization lock resources, wait will release the synchronization lock resources

    • Usage scope: sleep can be used anywhere, but wait can only be used in synchronized synchronization Use

    • Exception handling in methods or code blocks: sleep needs to catch exceptions, but wait does not need to catch exceptions

    2. wait method

    • Make the thread currently executing the code wait. (Put the thread in the waiting queue)

    • Release the current lock

    • Awakened when certain conditions are met, try to acquire the lock again.

    • wait must be used with synchronized. Using wait without synchronized will directly throw an exception.

    Use of wait method

    wait method

    /**
     * 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 thread with parameters and wait thread without parameters

    /**
     * 有参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();
        }
    }

    wait ends waiting Conditions

    ①Other threads call the notify method of the object.

    ②The wait waiting time times out (the wait method provides a version with a timeout parameter to specify the waiting time).

    ③Other threads call the interrupted method of the waiting thread, causing wait to throw an InterruptedException exception

    3. notify and notifyAll methods

    The notify method only wakes up a certain waiting thread

    1. The method notify() must also be called in a synchronized method or synchronized block. This method is used to notify other threads that may be waiting for the object lock of the object

    2. If there are multiple threads waiting, randomly select a thread in wait state

    3. After the notify() method, the current thread will not release the object lock immediately, and will wait until notify() is executed. The thread of the method will finish executing the program, that is, the object lock will be released after exiting the synchronized code block.

    Using the notify method

    /**
     * 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 method can wake up all at once Waiting thread

    Usage of notifyAll method

    /**
     * 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();
        }
    }

    The difference between notify and notifyAll methods

    1. When you call notify, only one waiting thread will be awakened And it doesn't guarantee which thread will be woken up, it depends on the thread scheduler.

    2. Call notifyAll method, then all threads waiting for the lock will be awakened, but before the remaining code is executed, all awakened threads will compete for the lock, which is why in the loop Because if multiple threads are woken up, the thread that will acquire the lock will execute first and it may reset the wait condition, which will force subsequent threads to wait.

    3. So, the key difference between notify and notifyAll is that notify() will wake up only one thread, while notifyAll method will wake up all threads.

    The above is the detailed content of What is the difference between sleep and wait methods in Java?. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete