1. The wait method and the Notify method
Both methods, including the Notifyall method, are methods in the object class. In the Java api, the wait method is defined as Follows:
Public final void Wait () throws Interruptedexception
causes the current thread to wait until another thread invokes the
notify()
method or the method for this
notifyAll()
object. I N other words, This method behaves exactly as if it simply performs the call
wait(0)
.
The current thread must own this object ' s Monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object ' s Mon Itor to wake up either through a call to the notify
method or the notifyAll
method. The thread then waits until it can re-obtain ownership of the monitor and resumes Execution.
As in the one argument version, interrupts and spurious wakeups is possible, and this method should always being used in a l Oop:
Synchronized (obj) { while (<condition does not hold>) obj.wait (); ...//Perform action appropriate to condition
This method, should only being called by a thread, is the owner of this object ' s Monitor. See the
notify
method for a description of the ways in which a thread can become the owner of a monitor.
In Java, you can use wait, notify, and notifyall to implement Inter-thread Communication. When a thread is running, it can call the wait method to pause its execution if certain conditions are found to be not satisfied, and then discard the acquired lock and enter the wait State. When the thread is awakened by another thread and acquired a lock, it can continue to execute backwards where it was previously paused, rather than starting again from where the synchronization code block Started. It is important to note, however, that the criteria for waiting for threads are judged using while rather than if . When the thread is awakened, it will again determine whether the condition is Satisfied.
Imagine a producer, Multi-consumer scenario. A consumer Consumer1 the last element and wakes up other threads, and if the wake is exactly Consumer2, then there is no element to Consume. If you use the IF judgment, the condition is not judged again after being awakened, but it is executed directly to cause a run Error. Our code is as Follows:
The Notify method wakes the thread that waits for an object lock, but specifically wakes which is Indeterminate.
2. Realization of producer consumers
Use if to determine if the program will cause an error
Be sure to use while to judge the Thread's wait condition instead of using the IF
1 packagethread.learn;2 3 Importjava.util.LinkedList;4 Importjava.util.Queue;5 Importjava.util.Random;6 7 /**8 * Created by Liujinhong on 2017/4/2.9 * Producer Consumer problem is a very classic problem, it is worth studyingTen * Java's wait and notify methods are also very important to Use. one */ a public classProducerconsumer { - public Static classProducerextendsThread { -Queue<integer>queue; the intmaxsize; - -Producer (queue<integer> Queue,intmaxsize, String Name) { - this. Queue =queue; + this. maxsize =maxsize; - this. SetName (name); + } a @Override at public voidRun () { - while(true) { - synchronized(queue) { - Try{ -Thread.Sleep (500); -}Catch(Exception E) {} in -System.out.println ( this. getName () + "get lock on queue"); to //the condition must be judged using while rather than if + if(queue.size () = =Maxsize) { -System.out.println ("queue is full, producer" + this. getName () + "wait"); the Try { * queue.wait (); $}Catch(Exception E) {}Panax Notoginseng } - intnum = (int) (math.random () *100); the Queue.offer (num); + aSystem.out.println ( this. getName () + "production of an element:" +num); the Queue.notifyall (); + -System.out.println ( this. getName () + "quit a production process!" "); $ } $ } - } - } the - public Static classConsumerextendsThread {WuyiQueue<integer>queue; the intmaxsize; - wuConsumer (queue<integer> Queue,intmaxsize, String Name) { - this. Queue =queue; about this. maxsize =maxsize; $ this. SetName (name); - } - - @Override a public voidRun () { + while(true) { the synchronized(queue) { - Try{ $Thread.Sleep (500); the}Catch(Exception E) {} the theSystem.out.println ( this. getName () + "get lock on queue"); the //the condition must be judged using while rather than if - if(queue.isempty ()) { inSystem.out.println ("queue is empty, consumer" + this. getName () + "wait"); the Try{ the queue.wait (); about}Catch(Exception E) {} the } the intnum =Queue.poll (); theSystem.out.println ( this. getName () + "consume an element:" +num); + Queue.notifyall (); - theSystem.out.println ( this. getName () + "quit a consuming process!" ");Bayi } the } the } - } - the public Static voidmain (string[] Args) { thequeue<integer> queue =NewLinkedlist<>(); the intMaxSize = 2; the -Producer Producer =NewProducer (queue, maxsize, "Producer"); theConsumer Consumer1 =NewConsumer (queue, maxsize, "Consumer1"); theConsumer Consumer2 =NewConsumer (queue, maxsize, "Consumer2"); theConsumer Consumer3 =NewConsumer (queue, maxsize, "Consumer3");94 the Producer.start (); the Consumer1.start (); the Consumer2.start ();98 Consumer3.start (); about } -}
Use of the Wait () and notify () methods in Java