Relevant methods of waiting/notification
Method name | describe |
---|---|
notify() | Notify a thread that waits on an object, changes from WAITING state to BLOCKING state, moves from waiting queue to synchronous queue, waits for CPU scheduling to acquire the lock of the object, and when the thread acquires the lock of the object, the thread returns from wait() method. |
notifyAll() | Notify all threads waiting on the object, from WAITING state to BLOCKING state, and wait for CPU scheduling to acquire the lock of the object |
wait() | The thread invoking this method enters the WAITING state and places the current thread in the waiting queue of the object. It will return only after waiting for notification or interruption from another thread. It should be noted that the lock of the object will be released after calling the wait() method. |
wait(long) | The parameter time here is milliseconds, that is to say, the waiting time is n milliseconds. If there is no notification, the time-out returns. |
wait(long,int) | For more detailed control of timeout time, nanoseconds can be achieved |
Note: The above method must obtain the lock of the object before it can be invoked, otherwise IllegalMonitorStateException will be thrown.
Throws:
IllegalMonitorStateException - if the current thread is not the owner of this object's monitor.
Waiting notification mechanism means that one thread A calls the wait() method of object O to enter the waiting state, while another thread B calls the notify() or notifyAll() method of object O. After receiving the notification, thread A returns from the wait() method of object O to perform subsequent operations. These two threads interact through object O, and the relationship between wait() and notify / notify all () on the object is just like a switch signal, which is used to complete the interaction between the waiting party and the notifying party.
public class WaitNotify{
static boolean flag = true;//There is no need to be volatile, because the operation of flag is under the protection of synchronized lock, which guarantees the memory visibility of flag.
static Object lock = new Object();
public static void main(String args[]) throws Exception{
Thread waitThread = new Thread(new Wait(),"WaitThread");
waitThread.start();
TimeUnit.SECONDS.sleep(1);//1 second -> package java.util.cocurrent
Thread notifyThread = new Thread(new Notify(),"NotifyThread");
notifyThread.start();
}
static class Wait implements Runnable{
public void run(){
//Lock, monitor with lock
synchronized(lock){
//When the condition is unsatisfactory, continue wait ing while releasing lock lock
while(flag){
try{
System.out.println("flag is ture, Wait");
lock.wait();
}catch(InterruptedException e){
//In addition to notify notifications, wait() methods with timeouts and thread interrupt mechanisms can also wake up this thread
}
}
System.out.println("flag is false,complete");
}
}
}
static class Notify implements Runnable{
public void run(){
synchronized(lock){
//Get the lock of the lock, and then notify that the lock will not be released until the current thread releases the lock, calls notifyAll, and after WaitThread gets the lock, the wait thread can not return from the wait() method.
System.out.println("Notify get lock ,begin notify");
lock.notifyAll();
flag = false;
TimeUnit.SECONDS.sleep(5);
}
synchronized(lock){
System.out.println("Notify get lock again");
}
}
}
}