Java multithreading-Condition, multithreading-condition
ConditionSetObjectMonitor method (wait,notifyAndnotifyAll) Into different objects, so thatLockTo provide multiple waiting sets (wait-set) for each object ). Where,LockReplacedsynchronizedUse of methods and statements,ConditionReplaces the use of the Object monitor method.
Let's take a look at a simple example of Condition:
1 public class ConditionTest {2 public static void main (String [] args) {3 final Lock lock = new ReentrantLock (); 4 final Condition condition = lock. newCondition (); 5 6 Thread thread1 = new Thread (new Runnable () {7 @ Override 8 public void run () {9 try {10 lock. lock (); 11 System. out. println ("I need to wait for a signal" + this); 12 condition. await (); 13 System. out. println ("I got a signal" + this); 14} catch (Exception e) {15 // TODO: handle exception16} finally {17 lock. unlock (); 18} 19 20 21} 22}, "thread1"); 23 thread1.start (); 24 Thread thread2 = new Thread (new Runnable () {25 @ Override26 public void run () {27 try {28 lock. lock (); 29 System. out. println ("I got the lock"); 30 Thread. sleep (500); 31 System. out. println ("I am sending a signal"); 32 condition. signal (); 33} catch (Exception e) {34 // TODO: handle exception35} finally {36 lock. unlock (); 37} 38 39 40} 41}, "thread2"); 42 thread2.start (); 43} 44}
Running result:
1. I need to wait for a signal com. luchao. traditionalthread. conditionTest $1 @ 10bc3c92 I got the lock 3 I sent a signal 4 I got a signal com. luchao. traditionalthread. conditionTest $1 @ 10bc3c9View Code
It can be seen that the Condition execution method is that when the await method is called in thread 1, thread 1 will release the lock and sleep itself, waiting to wake up. After thread 2 obtains the lock, call the signal method of Condition to wake up thread 1 and thread 1 to resume execution.
The preceding description shows that Condition is a tool class for coordinated communication among multiple threads, so that one or more threads can wait for a Condition. Only when the Condition is met (the signal or signalAll method is called) wait for the thread to wake up and compete for the lock again.
Condition is similar to traditional thread communication. It is widely used and can communicate multiple threads to complete more complex communication.
Use Condition to replace traditional thread communication. In the previous tradition, the sub-thread and the main thread run 50 times in turn, and the Condition can also be used.
The Code is as follows:
1 public class ConditionCommuniction { 2 public static void main(String[] args) { 3 final Business business = new Business(); 4 new Thread(new Runnable() { 5 @Override 6 public void run() { 7 for (int i = 0; i < 50; i++) { 8 business.sub(i); 9 }10 }11 }).start();12 for (int i = 0; i < 50; i++) {13 business.main(i);14 }15 }16 17 18 static class Business{19 private Lock lock = new ReentrantLock();20 private boolean isMain = true;21 private Condition condition = lock.newCondition();22 public void main(int i){23 lock.lock();24 try {25 while(!isMain){26 condition.await();27 }28 for (int j = 0; j < 100; j++) {29 System.out.println("main is looping :" + j +" in " + i);30 }31 isMain = false;32 condition.signal();33 } catch (Exception e) {34 // TODO: handle exception35 } finally{36 lock.unlock();37 }38 }39 public void sub(int i){40 lock.lock();41 try {42 while(isMain){43 condition.await();44 }45 for (int j = 0; j < 10; j++) {46 System.out.println("sub is looping :" + j +" in " + i);47 }48 isMain = true;49 condition.signal();50 } catch (Exception e) {51 // TODO: handle exception52 } finally{53 lock.unlock();54 }55 }56 }57 }
In Condition, await () is used to replace wait (), signal () with policy (), and signalAll () with policyall (). In the traditional thread communication mode, condition can be implemented. Note that Condition is bound to the Lock. The newCondition () method must be used to create a Lock.
In this case, there is no difference between Condition and traditional thread communication. The power of Condition is that it can create different Condition for multiple threads. Next we will introduce a piece of code in the API to illustrate it.
1 class BoundedBuffer {2 final Lock lock = new ReentrantLock (); // lock Object 3 final Condition notFull = Lock. newCondition (); // write the thread Condition 4 final Condition notEmpty = lock. newCondition (); // read thread condition 5 6 final Object [] items = new Object [100]; // cache queue 7 int putptr/* write Index */, takeptr/* read Index */, count/* Number of data in the queue */; 8 9 public void put (Object x) throws InterruptedException {10 lock. lock (); 11 try {12 while (count = items. length) // If the queue is full 13 notFull. await (); // blocking write thread 14 items [putptr] = x; // assign a value of 15 if (++ putptr = items. length) putptr = 0; // If the write index is written to the last position of the queue, it is set to 0 16 + + count; // number + 17 notEmpty. signal (); // wake up read thread 18} finally {19 lock. unlock (); 20} 21} 22 23 public Object take () throws InterruptedException {24 lock. lock (); 25 try {26 while (count = 0) // If the queue is empty 27 notEmpty. await (); // blocked read thread 28 Object x = items [takeptr]; // value 29 if (++ takeptr = items. length) takeptr = 0; // If the read index reads the last position of the queue, it is set to 0 30 -- count; // number -- 31 notFull. signal (); // wake up write thread 32 return x; 33} finally {34 lock. unlock (); 35} 36} 37}
This is the power of multiple conditions. If the cache queue is full, the blocking must be a write thread, and the wake-up must be a read thread. On the contrary, the blocking must be a read thread, the wake-up process must be a write thread. If there is only one Condition, what is the effect? The cache queue is full. This Lock does not know whether to wake up the read thread or write thread, it is a great pleasure to wake up the read thread. If it is a write thread, the thread will be awakened and blocked again, and then wake up again, which wastes a lot of time.
Expand the program that runs alternately with the main thread and sub-thread, and run the three threads alternately. The Code is as follows:
1 public class ThreeConditionCommunication {2 public static void main (String [] args) {3 final Business business = new Business (); 4 new Thread (new Runnable () {5 6 @ Override 7 public void run () {8 for (int I = 0; I <50; I ++) {9 business. sub1 (I); 10} 11} 12 }). start (); 13 new Thread (new Runnable () {14 15 @ Override16 public void run () {17 for (int I = 0; I <50; I ++) {18 business. sub2 (I); 19} 20} 2 1 }). start (); 22 for (int I = 0; I <50; I ++) {23 business. main (I); 24} 25} 26 static class Business {27 Lock lock = new ReentrantLock (); 28 Condition main = lock. newCondition (); 29 Condition sub1 = lock. newCondition (); 30 Condition sub2 = lock. newCondition (); 31 int runNum = 1; 32 33 public void main (int I) {34 lock. lock (); 35 try {36 while (runNum! = 1) {37 main. await (); // The main thread waits for 38} 39 for (int j = 0; j <100; j ++) {40 System. out. println ("main is looping of" + j + "in" + I); 41} 42 runNum = 2; 43 sub1.signal (); // wake up sub-thread 144} catch (Exception e) {45 // TODO: handle exception46} finally {47 lock. unlock (); 48} 49} 50 public void sub1 (int I) {51 lock. lock (); 52 try {53 while (runNum! = 2) {54 sub1.await (); // subthread 1 wait 55} 56 for (int j = 0; j <10; j ++) {57 System. out. println ("sub1 is looping of" + j + "in" + I); 58} 59 runNum = 3; 60 sub2.signal (); // wake up sub-thread 261} catch (Exception e) {62 // TODO: handle exception63} finally {64 lock. unlock (); 65} 66} 67 public void sub2 (int I) {68 lock. lock (); 69 try {70 while (runNum! = 3) {71 sub2.await (); // subthread 2 wait 72} 73 for (int j = 0; j <20; j ++) {74 System. out. println ("sub2 is looping of" + j + "in" + I); 75} 76 runNum = 1; 77 main. signal (); // wake up Master thread 78} catch (Exception e) {79 // TODO: handle exception80} finally {81 lock. unlock (); 82} 83} 84} 85}
It can be seen that Condition plays a powerful role in multi-thread communication and can greatly improve program efficiency.