From: http://blog.csdn.net/zyplus/article/details/6672775
Have the appropriate code modifications.
In Java, there are no similar methods related to PV operations, process mutexes, 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 the mutex memory block, in Java in the object type, all with a memory lock, After a thread acquires the memory lock, other threads cannot access the memory, enabling simple synchronization and mutex operations in Java. Understand this principle, can understand why synchronized (this) and synchronized (static XXX) difference, synchronized is to apply memory lock for memory block, this keyword represents an object of the class, So its memory lock is a mutex for the same object, and the static member belongs to the class proprietary, and its memory space is common to all members of the class, which causes synchronized () to lock the static member, which is equivalent to locking the class, that is, to implement mutual exclusion among all members of the class. Only one thread at a time can access instances of the class. If you simply want to implement a thread mutex in Java, it's enough to understand that. But if you need to wake up between threads, you need to use object.wait (), object.nofity ().
Obj.wait (), and obj.notify () must be used with synchronized (obj), that is, wait, and notify is for the OBJ lock that has been acquired, from a syntactic point of view is 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, while this thread sleeps. Until the thread is awakened by another thread calling the object's notify (), it can continue to acquire the object lock and continue execution. The corresponding notify () is the wake-up operation of the object lock. But one thing to note is that after the Notify () call, the object lock is not released immediately, but after the corresponding synchronized () {} statement block executes and the lock is automatically freed, the JVM randomly picks a thread in the Wait () object lock, assigns its object lock, wakes the thread, Continue execution. 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 main difference being that object.wait () releases the control of the object lock while releasing the CPU.
It is not enough to have a clear understanding of the concept alone, and it needs to be tested in real-world examples to get a better understanding. Object.wait (), object.notify () application of the most classic example, it should be a three-way printing ABC problem, it is a more classic face test, the topic requirements are as follows:
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 run concurrently, and prints 10 times the ABC. This problem can be easily solved with object's Wait (), notify (). The code is as follows:
First to explain the overall idea, from the big direction, the problem is a three-way synchronous wake-up operation, the main purpose is to Threada->threadb->threadc->threada loop to execute three threads. In order to control the order in which threads are executed, it is necessary to determine the order of wake-up and wait, so each thread must hold two object locks at the same time to continue execution. An object lock is prev, which is the object lock held by the previous thread. There is also a lock on the object itself. The main idea is that in order to control the order of execution, 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 about it, you will find that there is a problem, that is, the initial conditions, three threads in accordance with the a,b,c sequence to start, according to the previous thinking, a wake-up b,b wake C,c and then wake A. However, this assumption relies on the sequence in which the JVM threads are dispatched and executed. Specifically, after the main thread starts Threada, it needs to be executed at Threada, when the prev.wait () waits, then the thread starts threadb,threadb execution, and when the prev.wait () waits, the main thread is cut back. To start THREADC, only the JVM executes in the order that the thread runs, to ensure that the output is correct. This relies on the specific implementation of the JVM. Consider a situation where the following is true: if the main thread executes a after starting a, the main thread is started, and THREADB,THREADC is initiated, and 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 get the prev is a object lock, THREADC execution conditions have been satisfied, will print C, then release C, and B object lock, then threadb have the operating conditions, will print B, that is, the cycle into ACBACB. In this case, you can use theActively release the CPU for impersonation. The code is as follows:
Public classMyThreadPrinter2ImplementsRunnable {PrivateString name; PrivateObject prev; PrivateObject Self; PrivateMyThreadPrinter2 (String name, Object prev, object self) { This. Name =name; This. prev =prev; This. Self =Self ; } Public voidrun () {intTime=3; intCount =Time ; while(Count > 0) { synchronized(prev) {synchronized(self) {System.out.print (name); Count--; Self.notify (); } //try {//Thread.Sleep (1);//} catch (Exception e) {//e.printstacktrace ();// } Try { if(count>0) {prev.wait (); } } Catch(interruptedexception e) {e.printstacktrace (); } } } //System.out.println ("------------" +name+ "--------->>>"); } Public Static voidMain (string[] args)throwsException {Object a=NewObject (); Object b=NewObject (); Object C=NewObject (); Object D=NewObject (); MyThreadPrinter2 PA=NewMyThreadPrinter2 ("A", D, a); MyThreadPrinter2 PB=NewMyThreadPrinter2 ("B", A, b); MyThreadPrinter2 PC=NewMyThreadPrinter2 ("C", B, c); MyThreadPrinter2 PD=NewMyThreadPrinter2 ("D", C, D); Thread AA=NewThread (PA); Aa.start (); Thread.Sleep (20); NewThread (Pb). Start (); Thread.Sleep (20); NewThread (PC). Start (); Thread.Sleep (20); NewThread (PD). Start (); } }
Java wait and notify sleep