First, preface
For concurrent programming, in addition to the thread, the Wati and notify objects for object objects should also have a deep understanding of their usage, although there are not many knowledge points.
II. basic knowledge of thread safety
First of all, the following basic points should be remembered, the first back is also no harm:
- At the same time a lock can only be held by one thread
- Call the object's Wait () and notify () before you must hold it
third, wait () and notify () understand3.1 Wait () and notify () methods Introduction
Wait () and notify () are both methods of object , which can be thought of as any object as a resource (or a representation of a resource), and when multiple threads operate on a resource, if the thread finds that the resource is not ready, it You can wait on this resource , called the Wait () method of the resource, and if there is another thread that has some processing that feels that the resource is available, it calls the Notify () method of this resource and tells the thread waiting for it that the resource can be used.
Of course, it is also possible not to use the wait () and notify () methods, which can be judged by a while () dead loop , such as the following pseudo-code:
class resource{ staticboolean canuse=false;} while (! resource.canuse) { // if not available, the dead loop is waiting here } // when a resource is available, it jumps out of the loop and executes
It is possible to do so, but special Consume CPU Resources , we recommend that you use the Wait () and notify () methods.
Value of 3.2 wait () and notify ()
In fact, from the word meaning can be seen, wait is waiting, indicating that this resource is not ready , I have to wait, and this one wait (long timeout), that I can only wait for you so long, outdated not waiting Ah, and call notify () Thread must be processing the resource and will be notified when it is processed. So, they are often used in producer and consumer models . any scenario involving the arrival of such resources is appropriate for these two methods ,
3.3 Why Wait () and notify () must be used with synchronized
When you are not using Wait () and notify () in the synchronized synchronization block or the object that is calling the method is not a synchronized synchronous lock, the exception is thrown:
Java.lang.IllegalMonitorStateException
Many people wonder why it is necessary to hold the lock on this object to invoke the Wait () and notify () methods of the object, and I have this confusion, and I think it is unnecessary to do so. First look at the following code:
Public classwaittest{//This is a resource that simulates the object FinalNOOBJCT resource=Newnoobjct (); Public Static voidMain (string[] args)throwsexception{waittest D=Newwaittest (); D.test (); } Public voidTest ()throwsexception{Runnable R=NewRunnable () { Public voidrun () {//invoke the simulated wait method for the resource, using synchronized inside the methodresource.nowait (); System.out.println ("Thread waits, executes"); } }; Thread T=NewThread (R); T.start (); Thread.Sleep (2000); System.out.println ("Ready to wake threads waiting for resources"); //invoke the Notify method of the resource's impersonation, using synchronized inside the methodresource.nonotify (); }}//because Wait () and notify () are the final methods and cannot be overwritten, a mock objectclassnoobjct{//simulate the Wait method Public voidnoWait () {//this is equivalent to putting the synchronized inside the Wait method . synchronized( This){ Try{ This. Wait (); }Catch(interruptedexception e) {e.printstacktrace (); } } } //Analog Notify Method Public voidnonotify () {//this is equivalent to putting the synchronized inside the Notify method . synchronized( This){ This. Notify (); } }}
This is a simple wait () and notify () example, wait waiting, notify wakeup. If you ignore the simulated object, you will find the code is a lot simpler, or you will need to use synchronized every time, the following code:
Public classwaittest{//This is a resource that simulates the object FinalObject resource=NewObject (); Public Static voidMain (string[] args)throwsexception{waittest D=Newwaittest (); D.test (); } Public voidTest ()throwsexception{Runnable R=NewRunnable () { Public voidrun () {//must use synchronized Try{ synchronized(Resource) {resource.wait (); } }Catch(interruptedexception e) {e.printstacktrace (); } System.out.println ("Thread waits, executes"); } }; Thread T=NewThread (R); T.start (); Thread.Sleep (2000); System.out.println ("Ready to wake threads waiting for resources"); //must use synchronized synchronized(Resource) {resource.notify (); } }}
So, I think that wait () and notify () and synchronized do not make any sense, after all synchronized used to do code synchronization, and thread wake-up is nothing to do (I hope readers can give me the opposite opinion and persuade me). But since that's the rule, you have to obey, that is, wait and notify must be used in synchronized, and the object that invokes the method must be a synchronization object.
Iv. When to use Wait () and notify ()
One of the values of the two methods mentioned above is used in the producer and consumer models. But the producer and consumer models used to build them are low-level and complex, and can be built entirely using the implementation classes of the Blockingqueue interface. For example, you can use Arrayblockingqueue, which can ensure both thread safety and blocking effect, why not.
In addition, only the threads sleep and wake up.
This article seems to have nothing to do with concurrency, but because it involves multithreading or a piggyback talk.
No reprint without permission.
The Wait (), notify (), Notifyall () method of the "Java Concurrency Series 02" Object uses