Combined with synchronized, you will better understand the two methods of 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. It allows the calling Thread to enter the sleep state and gives the execution opportunity 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 of static, it can not change the machine lock of an object. When a synchronized block calls sleep(), the thread is asleep, but the machine lock of the object is not released. Other threads still can not access the object.
The following is an example:
Service Class: public class Service { public void mSleep(){ synchronized(this){ try{ System.out.println(" Sleep . Current time:"+System.currentTimeMillis()); Thread.sleep(3*1000); } catch(Exception e){ System.out.println(e); } } } public void mWait(){ synchronized(this){ System.out.println(" Wait . End time:"+System.currentTimeMillis()); } } }
Two methods are defined. The mSleep() method will make the calling thread sleep for 3 seconds, and mWait() will print a sentence. Both methods use synchronous 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 the 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 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 sent to mService. That is to say, after the two threads are activated, they call the same Service object.
Let's look at the results first:
Sort out the logic:
Firstly, 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 does not release the lock of the Service object.
At this time, the waitThread thread also starts and calls the mWait method of the Service object. Similarly, the synchronization code block is reached. Because the lock of the Service object has been occupied by sleepThread, the waitThread thread can only wait.
mWait will not be called until the sleepThread thread releases the synchronization lock after the execution (sleep ends), and the waitThread thread obtains the synchronization lock and will continue to execute.
If sleepThread releases the machine lock, the task of waitThread will be executed immediately. It can be seen from the print result that the task of waitThread is executed after 3 seconds.
Synchronous lock, which locks an object. If a thread gets the machine lock of an object to execute a synchronization code block, other threads cannot execute other synchronization code blocks of the object.
In this example, the sleepThread thread obtains the synchronization lock of the service object and 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 section of code
synchronized(this){ System.out.println(" Wait . End time:"+System.currentTimeMillis()); }
I believe now that you have understood the results of the sleep method without releasing the machine lock, 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. You can wake up the waiting thread through the notify and notifyAll methods
The following modification procedure is as follows:
public class Service { public void mSleep(){ synchronized(this){ try{ Thread.sleep(3*1000); this.notifyAll(); System.out.println(" Wake up waiting. End time:"+System.currentTimeMillis()); } catch(Exception e){ System.out.println(e); } } } public void mWait(){ synchronized(this){ try{ System.out.println(" Wait for the start. Current time:"+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
Here, start the waitthread thread first, and then the waitthread thread enters the waiting state and releases the lock of the Service object. At this time, the sleepthread is also started and comes to the synchronization code block of the mSleep method. Because the previous waitthread thread has released the machine lock of the Service object, the sleepthread can get the object lock, so the mSleep method will be called immediately. Then the sleepThread thread is in the sleep state. After calling the notifyAll() for 3 seconds, the waitThread thread is awakened.
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
--------
Copyright notice: This article is the original article of CSDN blogger "yinhuanxu", which follows the CC 4.0 BY-SA copyright agreement. For reprint, please attach the source link of the original text and this notice.
Original link: https://blog.csdn.net/xyh269/article/details/52613507