This article is for Java's Wait (), notify (), Notifyall () for a detailed analysis of the introduction of a friend that needs reference under
Wait (), notify (), and Notifyall () are all methods of Java.lang.Object:
Wait (): Causes the current thread to wait until another thread invokes the Notify () method or the Notifyall () method for T His object.
Notify (): Wakes up a single thread, that's waiting on this object ' s monitor.
Notifyall (): Wakes up all threads is waiting on this object ' s monitor.
These three methods are the underlying mechanism provided by the Java language to implement inter-thread blocking (Blocking) and control in-process scheduling (inter-process communication). Before explaining how to use it, let's say two points:
1. Just as any object in Java can be a lock (lock), any object can also become a conditional queue (Condition queue). The Wait (), notify (), and Notifyall () in this object are the intrinsic (intrinsic) methods of this conditional queue.
2. An intrinsic lock of an object and its inherent conditional queue are related, in order to invoke the method of the conditional queue within object X, you must obtain the lock of Object X. This is because the mechanism of waiting for state conditions and the mechanism of guaranteeing state continuity are tightly combined.
(An object's intrinsic lock and its intrinsic condition queue is Related:in order to call any of the condition queue met Hods on object x, you must hold the lock on X. This was because the mechanism for waiting for state-based conditions are necessarily tightly bound to the mechanism fo pres Erving State consistency)
According to the above two points, when you call Wait (), notify () or Notifyall (), you must first obtain the lock, and the state variable should be protected by the lock, and the intrinsic lock object and the intrinsic condition queue object is the same object. That is, to execute wait,notify on an object, you must first lock the object, and the corresponding state variable is protected by that object lock.
After knowing how to use it, let's ask the following questions:
1. What happens when you do wait, notify, and do not get a lock?
Please look at the code:
The code is as follows:
Public Static void throws interruptedexception { new Object (); Obj.wait (); Obj.notifyall ();}
Executing the above code throws a Java.lang.IllegalMonitorStateException exception.
2. What happens when you execute wait, notify, without obtaining a lock on the object?
Please look at the code:
The code is as follows:
public static void Main (string[] args) throws interruptedexception {Object obj = new O Bject (); Object Lock = new Object (); synchronized (lock) {obj.wait (); Obj.notifyall (); } }
Executing the code will also throw a java.lang.IllegalMonitorStateException exception.
3. Why do I have to get a lock on this object when I execute wait, notify? This is because, if there is no lock, wait and notify may produce a race condition (Race Condition). Consider the following producers and consumers: 1.1 producer check conditions (e.g. full cache), 1.2 producers must wait for 2.1 consumers to consume a unit of cache--2.2 to reset the condition (such as cache not full), 2.3 call Notifyall () Wake-up producers The order we want is: 1.1->1.2->2.1->2.2->2.3 but in multithreaded situations, the order is likely to be 1.1->2.1->2.2->2.3->1.2. In other words, before the producers wait, the consumer is notifyall, so that the producers will keep waiting. Therefore, to solve this problem, you must obtain the lock of the object during wait and notifyall to ensure synchronization. Consider the following simple model of caching for a producer, a consumer, and a unit implemented using wait,notify:
The code is as follows:
Public classQueuebuffer {intN; BooleanValueSet =false; synchronized intget () {if(!ValueSet)Try{wait (); } Catch(interruptedexception e) {System.out.println ("Interruptedexception caught"); } System.out.println ("Got:" +N); ValueSet=false; Notify (); returnN; } synchronized voidPutintN) {if(ValueSet)Try{wait (); } Catch(interruptedexception e) {System.out.println ("Interruptedexception caught"); } This. N =N; ValueSet=true; System.out.println ("Put:" +N); Notify (); }}
The code is as follows:
Public classProducerImplementsRunnable {PrivateQueuebuffer Q; Producer (Queuebuffer q) { This. Q =Q; NewThread ( This, "Producer"). Start (); } Public voidrun () {inti = 0; while(true) {Q.put (i++); }}} code is as follows: Public classConsumerImplementsRunnable {PrivateQueuebuffer Q; Consumer (Queuebuffer q) { This. Q =Q; NewThread ( This, "Consumer"). Start (); } Public voidrun () { while(true) {q.get (); } }}
Public class Main { publicstaticvoid main (string[] args) { new Queuebuffer (); New Producer (q); New Consumer (q); System.out.println ("Press Control-c to stop.") ); }}
Therefore, the JVM illegalmonitorstateexception the hidden race Condition by throwing an exception at execution time to ensure that the object is locked for wait, notify. Finally, take a look at a topic: Write a multithreaded program, alternating output 1,2,1,2,1,2 ... Using Wait, notify solves: The code is as follows:
Public classOutputthreadImplementsRunnable {Private intnum; PrivateObject Lock; PublicOutputthread (intnum, Object Lock) { Super(); This. num =num; This. Lock =lock; } Public voidrun () {Try { while(true){ synchronized(lock) {lock.notifyall (); Lock.wait (); SYSTEM.OUT.PRINTLN (num); } } } Catch(interruptedexception e) {//TODO auto-generated Catch blockE.printstacktrace (); } } Public Static voidMain (string[] args) {FinalObject lock =NewObject (); Thread Thread1=NewThread (NewOutputthread (1, lock)); Thread thread2=NewThread (NewOutputthread (2, lock)); Thread1.start (); Thread2.start (); }}
Http://www.jb51.net/article/40746.htm
Java Wait (), notify () and Notifyall () usage (RPM)