JAVA Wait (), notify (), sleep specific explanation

Source: Internet
Author: User


After Csdn opened a blog, has not been published on the above article, until a period of time with a predecessor of the dialogue, only to discover the importance of technology blog, determined to put CSDN blog to build well. But has not found a good opening theme, today, see Java threads mutually exclusive, synchronous time and have a new experience, as he begins.

In Java, there are no similar methods related to PV operations, process repulsion, and so on. Java's process synchronization is achieved through synchronized (), it should be explained that the Java synchronized () method is similar to the operating system concept of mutually exclusive blocks of memory, in Java in the object type, is a memory lock, After the memory lock is fetched by the thread thread, other threads cannot access the memory, enabling simple synchronization and mutually exclusive operations in Java. Clear this principle, can understand why synchronized (this) and synchronized (static XXX) difference, synchronized is the memory block for Memory lock, Thiskeyword represents an object of the class, So its memory lock is a mutually exclusive operation against the same object, and the static member belongs to the class proprietary, and its memory space is owned by all members of the class, which causes synchronized () to lock the static member, which is equivalent to lock the class, that is, to achieve mutual exclusion among all members of the class. At the same time, only one thread can access an instance of the class. Let's just say that the simple truth is that threads in Java now repel each other, and it's enough to be clear about these basics. However, it is necessary to use object.wait () and object.nofity () if it is necessary to wake each other between threads.

Obj.wait (), and obj.notify () must be used with synchronized (obj), that is, wait, and notify is for operations that have acquired the OBJ lock, from a syntactic point of view, obj.wait (), Obj.notify must be in synchronized (OBJ) {...} Within the statement block. Functionally, wait means that the thread is actively releasing the object lock after acquiring the object lock, and this thread sleeps at the same time. Until another thread calls the object's notify () to wake the thread, the talent continues to acquire the object lock and continues to run. The corresponding notify () is the wake-up operation of the object lock. One thing to note, however, is that the Notify () call does not immediately release the object lock, but instead, after the corresponding synchronized () {} statement block runs, the JVM will randomly pick a thread in the Wait () object lock, give its object lock, wake the thread , continue to run. This provides a synchronous, wake-up operation between threads. Both Thread.Sleep () and object.wait () can pause the current thread and release the CPU control, the basic difference being that object.wait () releases the control of the object lock at the same time that the CPU is freed.

It is not enough to have a clear understanding of the concept alone, and it is necessary to have a better understanding of the test ability in the actual example. Object.wait (), object.notify () application of the most classic example, it should be a three-way printing ABC problem, it is a more classical surface test, the topic requirements such as the following:

Build three threads, a thread prints 10 times A, a thread prints 10 times b,c thread prints 10 times C, requires the thread to execute at the same time, alternating 10 times the ABC. This problem can be solved very conveniently with the wait () of object, notify (). The code is as follows:

 

public class MyThreadPrinter2 implements Runnable {private String name;       Private Object prev;         Private Object self;           Private MyThreadPrinter2 (String name, Object prev, object self) {this.name = name;           This.prev = prev;       This.self = self;           } @Override public void Run () {int count = 10; while (Count > 0) {synchronized (prev) {synchronized (self) {S                       Ystem.out.print (name);                                          count--;                   Self.notify ();                   } try {prev.wait ();                   } catch (Interruptedexception e) {e.printstacktrace ();  }}}} public static void Main (string[] args) throws Exception {Object           A = new Object ();           Object B = new Object (); Object C= new Object ();           MyThreadPrinter2 pa = new MyThreadPrinter2 ("A", C, a);           MyThreadPrinter2 PB = new MyThreadPrinter2 ("B", A, b);                                 MyThreadPrinter2 pc = new MyThreadPrinter2 ("C", B, c);        New Thread (PA). Start ();        New Thread (Pb). Start ();    New Thread (PC). Start ();   }   }




     first to explain the general idea, from the big direction, the problem is a three-way synchronous wake-up operation, the basic purpose is to threada->threadb->threadc-> The Threada Loop runs three of threads. In order to control the order in which threads run, it is necessary to determine the order of wake-up and wait, so each thread must hold two object locks at the same time, and the ability to continue running. An object lock is prev, which is the object lock held by the previous thread. The other is its own object lock. The basic idea is that in order to control the order of operation, you must first hold the Prev lock, but also the previous thread to release its own object lock, and then to apply their own object lock, both print, and then first call Self.notify () to release their object lock, wake up the next waiting thread, Call Prev.wait () to release the Prev object lock, terminate the current thread, wait for the loop to end and wake again. Running the above code, you can find that three threads cycle to print ABC, a total of 10 times. The main process of running the program is a thread first run, hold C,a object lock, Release A,c lock, Wake B. Thread B waits for a lock, then applies a b lock, then prints B, then releases the B,a lock, wakes C, thread C waits for a B lock, then applies a c lock, then prints C, then releases the c,b lock, wakes a. There seems to be no problem, but if you think carefully, you will find that there is a problem, is the initial condition, three threads in accordance with the order of A,b,c to start, according to the previous thinking, a wake-up b,b wake C,c and then wake A. However, such assumptions depend on the order in which the JVM threads are dispatched and run. In detail, after the main main thread starts Threada, it needs to run after Threada, prev.wait () Wait, then cut back to the thread start threadb,threadb run, and wait in prev.wait (), then cut back to the main thread, Starting THREADC, only the JVM runs in the order that the thread runs, and the ability to ensure that the output is correct. This relies on the detailed implementation of the JVM. Consider a situation such as the following: Assuming that the main thread is running a after starting a, the process also cuts back to the main thread, starts THREADB,THREADC, and then, since the a thread has not yet released Self.notify, that is, B needs to wait at synchronized (prev). At this point, C calls synchronized (prev) to acquire the object lock on B. In this way, after a call, at the same time THREADB acquired the prev is a object lock, the operating conditions of THREADC has been satisfied, will print C, then release C, and B object lock, then threadb have the operating conditions, will print B, that is, the cyclic changehas become a ACBACB. In this case, the simulation can be performed by actively releasing the CPU in run. The code is as follows:

    public void Run () {           int count = ten;           while (Count > 0) {               synchronized (prev) {                   synchronized (self) {                       System.out.print (name);                       count--;                      try{                    Thread.Sleep (1);                    }                    catch (Interruptedexception e) {                     e.printstacktrace ();                    }                                        Self.notify ();                   }                   try {                       prev.wait ();                   } catch (Interruptedexception e) {                       e.printstacktrace ();                   }             }}       }   



After the execution of the printing results will become ACBACB. To avoid such uncertainties associated with JVM scheduling. The a,b,c three threads need to be started in a certain order, finally the code is the following:

 

  public class MyThreadPrinter2 implements Runnable {private String name;       Private Object prev;         Private Object self;           Private MyThreadPrinter2 (String name, Object prev, object self) {this.name = name;           This.prev = prev;       This.self = self;           } @Override public void Run () {int count = 10; while (Count > 0) {synchronized (prev) {synchronized (self) {S                       Ystem.out.print (name);                      count--;                    try{Thread.Sleep (1);                    } catch (Interruptedexception e) {e.printstacktrace ();                   } self.notify ();                   } try {prev.wait ();                  } catch (Interruptedexception e) {e.printstacktrace (); }}}} public static void Main (string[] args) throws Exception {Objec           t a = new Object ();           Object B = new Object ();           Object c = new Object ();           MyThreadPrinter2 pa = new MyThreadPrinter2 ("A", C, a);           MyThreadPrinter2 PB = new MyThreadPrinter2 ("B", A, b);                                 MyThreadPrinter2 pc = new MyThreadPrinter2 ("C", B, c);        New Thread (PA). Start ();        Thread.Sleep (10);        New Thread (Pb). Start ();        Thread.Sleep (10);        New Thread (PC). Start ();    Thread.Sleep (10);    }   }


This ability to solve the problem perfectly. Through this example also want to explain, very many theories, concepts such as obj.wait (), obj.notify (), and so on, understanding, relatively simple, but in the actual application, here is often the fault of the place. Need more in-depth understanding. And in the process of solving this problem, deepen the mastery of the concept.

--Welcome Reprint, please specify the source http://blog.csdn.net/zyplus--

JAVA Wait (), notify (), sleep specific explanation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.