Deep understanding of sleep() and wait()

Posted by bostonmacosx on Sat, 22 Jan 2022 14:21:48 +0100

preface

sleep method and wait method are two very confusing concepts, which are often asked. This paper introduces the characteristics of the two methods and the differences between the two methods, which is helpful for us to understand and distinguish.

1, sleep()

The sleep() method is a method in the Thread class. Calling this method will cause the current Thread to sleep

The following is a case to explain the specific usage scenario of sleep method

package com.ffyc.thread.day1;

public class Example {
    public static void main(String[] args) {
        Thread thread1=new Thread(()->{
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()+"Exporting"+i);
                if(i==2){
                    try {
                        System.out.println(Thread.currentThread().getName()+"I'm asleep");
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        Thread thread2=new Thread(()->{
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "Exporting" + i);
            }
        });
        thread1.start();
        thread2.start();
    }
}


At the same time, two threads were opened, and the sleep (3000) method was invoked in the execution of Thread1. The purpose was to let the thread sleep for 3000 milliseconds at a certain time, so that another thread could get the chance to execute. It is not until thread1 sleep time consumption is completed that you have the opportunity to obtain CPU usage.
Note: after the sleep time is over, the thread will switch to the ready state and execute only when it grabs the execution right of the cpu

From the above case, we can also see the other two characteristics of sleep method
1. When the cpu is released to other threads, its monitoring state remains unchanged, and the sleep state will be automatically released after the specified time, so we don't need to wake up.
2. Exception must be thrown or caught when calling sleep method

2, wait()

The wait() method is a method in the Object class. Calling this method will cause the thread to enter the WAITING state and need to wait for the notification of other threads before returning.


When the parameter is 0, wait for an infinite time, and a negative number will be thrown to Java Lang.illegalargumentexception exception

Explain the use scenario of wait method with producer and consumer problems

Counter code

public class Count {
    int number=0;
    public synchronized void add() throws InterruptedException {
        //When using the synchronization method (non static), use the current object this as the synchronization lock. Ensure that an object is the same lock
        if (number==0){
          this.notify();
          number++;
            System.out.println("The producer produced a product");
            System.out.println("Current counter product quantity:"+number);
        }
        this.wait();
    }
    public synchronized  void sub() throws InterruptedException {
        if(number==1){
            this.notify();
            number--;
            System.out.println("Consumers consume a product");
            System.out.println("Current counter product quantity:"+number);
        }
        this.wait();
    }
}

Producer code

public class Product extends Thread{
    Count c;
    public Product(Count c) {
        this.c = c;
    }
    public void run() {
        while(true){
            try {
                c.add();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Consumer code

public class Consumer extends Thread{
    Count c;
    public Consumer(Count c) {
        this.c = c;
    }
    @Override
    public void run() {
        while(true){
            try {
                c.sub();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Test code

public class CountTest {
    public static void main(String[] args) {
        Count count=new Count();
        Consumer c=new Consumer(count); //Two threads share an object, which ensures that two threads operate on the same variable
        Product p=new Product(count);
        c.start();
        p.start();
    }
}

Operation results

In the above example, we use the synchronized keyword to synchronize the production and consumption of goods. Every time a product is generated, we call the wait() method to put the current thread in the waiting state and wait for the consumer thread to consume. When the consumer thread finds no goods during task execution, it calls notify() to wake up the waiting producer thread on the corresponding synchronization lock and let the producer thread continue production, So as to continuously achieve orderly and balanced supply and demand.

From the above example, we can see the characteristics of wait()
1. You also need to catch or throw exceptions
2. When the wait() method is called, the thread will release the object lock and enter the waiting lock pool of this object. Only when the notify method is called for this object will it be awakened. It will not recover automatically as soon as the sleep method expires.

3, The difference between sleep() and wait()

The differences between sleep and wait are summarized below
1. The sleep method belongs to the Thread class and the wait method belongs to the Object class.
2. The sleep method pauses the execution for the specified time and gives up the CPU to other threads, but its monitoring state remains. After the specified time, it will automatically resume the running state.
3. During the call of sleep method, the thread will not release the object lock
4. When the wait() method is called, the thread will release the object lock and enter the waiting lock pool of this object. Only when the notify method is called for this object will it be awakened
5. The wait () method is generally used to synchronize code blocks or synchronization methods, and the sleep() method is more widely used

Note: the wait() method provides multiple overloaded methods. When the time parameter is passed in, the wait() method immediately enters the waiting state. When the time is up, it will wake up automatically without waking up The effect is similar to that of sleep. The only difference is that the wait method releases the lock object after entering the wait state, while the sleep method does not release the lock object during sleep.

summary

Readers are advised to review the thread state before reading this article. The difference between sleep() method and wait() can be remembered from three levels: 1 Method class 2 Whether to release the object lock 3 Whether it will wake up automatically. Readers can verify why the sleep() method does not release the lock object.

Topics: Java JavaSE