Wait () and Policy () are directly affiliated to the Object class, that is, all objects have this pair of methods. It seems incredible at the beginning, but it is actually quite natural, because this pair of methods will release the occupied lock when blocking, and the lock is owned by any object, the wait () method of any object is called to cause thread blocking and the lock on the object is released. However, calling the notify () method of any object causes the wait () method of the object to be called () method ).
Second, wait () and notify () can be called at any location, but this pair of methods must be called in the synchronized method or block for a very simple reason, the lock can be released only when the current thread occupies the lock in the synchronized method or block. In the same way, the lock on the object that calls this method must be owned by the current thread so that the lock can be released. Therefore, a method call must be placed in such a synchronized method or block. The lock object of this method or block is the object that calls these methods. If this item is not met, the program can still be compiled, but the IllegalMonitorStateException will occur at runtime.
The preceding features of the wait () and notify () methods determine that they are often used together with the synchronized method or block, by comparing them with the inter-process communication machine of the operating system, we will find their similarity: the synchronized method or block provides functions similar to the operating system primitive, their execution will not be affected by the multi-thread mechanism, and this pair of methods is equivalent to the block and wakeup primitives (both of which are declared as synchronized ). The combination of these algorithms allows us to implement a series of exquisite inter-process communication algorithms (such as semaphore algorithms) on the operating system and solve various complicated inter-thread communication problems.
The wait () and notify () methods are described as follows:
First, the thread that calls the notify () method to remove blocking is randomly selected from the thread that is blocked by calling the wait () method of the object, we cannot predict which thread will be selected, so we should be very careful when programming to avoid problems caused by such uncertainty.
Second: In addition to notify (), there is also a method notifyAll () that can also play a similar role. The only difference is that calling the notifyAll () method will call the wait () and all the blocked threads are all blocked at one time. Of course, only the thread that gets the lock can enter the executable state.
Demo for wait and notify:
01 /**
02 * <pre>
03 * The Sub-thread loops 10 times, the main thread loops 100 times, and then returns to the sub-thread loop 10 times,
04 * then return to the main thread for 100 cycles, so that the execution is 50 times
05 * </pre>
06 * @ author ketqi
07 */
08 public class waitpolicydemo {
09 public static void main (String [] args ){
10
11 final Business business = new Business ();
12 new Thread (new Runnable (){
13 @ Override
14 public void run (){
15 for (int I = 1; I <= 50; I ++ ){
16 business. sub (I );
17}
18
19}
20}). start ();
21
22 for (int I = 1; I <= 50; I ++ ){
23 business. main (I );
24}
25}
26}
27
28 class Business {
29 private boolean isMainThread = true;
30
31 public synchronized void sub (int I ){
32 while (! IsMainThread ){
33 try {
34 this. wait ();
35} catch (InterruptedException e ){
36 e. printStackTrace ();
37}
38}
39 for (int j = 1; j <= 10; j ++ ){
40 System. out. println ("sub thread sequence of" + j + ", loop of" + I );
41}
42 isMainThread = false;
43 this. Policy ();
44}
45
46 public synchronized void main (int I ){
47 while (isMainThread ){
48 try {
49 this. wait ();
50} catch (InterruptedException e ){
51 e. printStackTrace ();
52}
53}
54 for (int j = 1; j <= 100; j ++ ){
55 System. out. println ("main thread sequence of" + j + ", loop of" + I );
56}
57 isMainThread = true;
58 this. Policy ();
59}
60}