Difference between sleep() and wait()

 

Combined with synchronized, you will better understand the two methods sleep() and wait(), and of course you will know the difference between them. This blog will learn these two methods together

sleep()

The sleep() method is a static method of the thread class (Thread), which puts the calling thread into a sleep state and gives execution opportunities to other threads. After the sleep time is over, the thread enters the ready state and competes with other threads for the execution time of the CPU. 
Because sleep() is a static method, it cannot change the machine lock of the object. When the sleep() method is called in a synchronized block, although the thread goes to sleep, the machine lock of the object is not released, and other threads still cannot access it. object.

Here's an example to demonstrate:

Service class:

public class Service {

    public void mSleep(){
        synchronized(this){
            try{
                System.out.println(" Sleep 。当前时间:"+System.currentTimeMillis());
                Thread.sleep(3*1000);
            }
            catch(Exception e){
                System.out.println(e);
            }
        }
    }

    public void mWait(){
        synchronized(this){
            System.out.println(" Wait 。结束时间:"+System.currentTimeMillis());

        }
    }

}

There are two methods defined, the mSleep() method will make the calling thread sleep for 3 seconds, and mWait() will print a sentence. Both methods use synchronization locks.

SleepThread class:

public class SleepThread implements Runnable{

    private Service service;

    public SleepThread(Service service){
        this.service = service;
    }

    public void run(){
        service.mSleep();
    }

}

Thread class, used to call mSleep method of Service

WaitThread class:

public class WaitThread implements Runnable{

    private Service service;

    public WaitThread(Service service){
        this.service = service;
    }

    public void run(){
        service.mWait();
    }

}
  • Thread class, used to call the mWait method of the Service

Test class:

public class Test{
    public static void main(String[] args){

        Service mService = new Service();

        Thread sleepThread = new Thread(new SleepThread(mService));
        Thread waitThread = new Thread(new WaitThread(mService));
        sleepThread.start();
        waitThread.start();

    }

}

A Service object is created and assigned to mService, and two threads are created and passed to mService, that is to say, after the two threads are started, the method of the same Service object is called. 
First look at the results: 
write picture description here

Sort out the logic:

First, the sleepThread thread will start, and then call the mSleep method of the Service object in the run method. After the synchronization code block, this is the Service object mService created in the Test class. The sleepThread thread obtains the lock of the Service object, and then enters the sleep state. , but did not release the lock of the Service object. 
At this time, the waitThread thread is also started, and the mWait method of the Service object is called, and the synchronization code block is also reached. Because the lock of the Service object has been occupied by sleepThread, the waitThread thread can only wait. 
After the execution of the sleepThread thread is completed (the sleep is over), the synchronization lock is released, and the waitThread thread obtains the synchronization lock and will continue to execute, and mWait will be called.

If sleepThread releases the machine lock, the task of waitThread will be executed immediately. As can be seen from the print results, the task of waitThread is executed after 3 seconds.

A synchronization lock locks an object. If a thread acquires the machine lock of an object to execute a synchronized code block, then other threads cannot execute other synchronized code blocks of this object. 
In this example, the sleepThread thread gets the synchronization lock of the service object, sleeps after entering, but does not release the machine lock, then the waitThread thread cannot execute other synchronization code blocks of the service object, that is, it cannot enter this code.

synchronized(this){
            System.out.println(" Wait 。结束时间:"+System.currentTimeMillis());

}

I believe that now you have understood what the sleep method will bring if the machine lock is not released, then continue to wait

wait()

wait() is a method of the Object class. When a thread executes the wait method, it enters a waiting pool related to the object, and releases the machine lock of the object so that other threads can access it. It can be accessed through the notify and notifyAll methods. to wake up the waiting thread

The following modification program is as follows:

public class Service {

    public void mSleep(){
        synchronized(this){

            try{
                Thread.sleep(3*1000);
                this.notifyAll();
                System.out.println(" 唤醒等待 。 结束时间:"+System.currentTimeMillis());
            }
            catch(Exception e){
                System.out.println(e);
            }

        }

    }

    public void mWait(){

        synchronized(this){
            try{
                System.out.println(" 等待开始 。 当前时间:"+System.currentTimeMillis());
                this.wait();
            }catch(Exception e){
                System.out.println(e);
            }
        }

    }

}

Test class:

public class Test{

    public static void main(String[] args){

        Service mService = new Service();

        Thread sleepThread = new Thread(new SleepThread(mService));
        Thread waitThread = new Thread(new WaitThread(mService));
        waitThread.start();
        sleepThread.start();

    }

}

Also look at the print results first 
write picture description here

Here is to start the waitThread thread first, then the waitThread thread enters the waiting state and releases the lock of the Service object. At this time, sleepThread is also started and comes to the synchronization code block of the mSleep method, because the previous waitThread thread has released the Service object. The machine lock, sleepThread can get the object lock, so the mSleep method will be called immediately. Then the sleepThread thread enters the sleep state, and calls notifyAll() to wake up the waitThread thread after the 3-second sleep is over.

To sum up: 
The difference between sleep() and wait() is that the thread calling the sleep method will not release the object lock, while calling the wait() method will release the object lock

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327065763&siteId=291194637