Concept
Threads are independent individuals in the operating system, but these individuals cannot become a whole without special processing, and communication between threads becomes one of the necessary methods for the whole. When a thread has a communication command, the interaction between the systems is more powerful, while increasing CPU utilization also enables the developer to effectively control and supervise the process of threading tasks.
Use the Wait/notify method for communication between threads, note:
1. Wait and notify must be used with synchronized keyword
2. Wait method release lock, notify method does not release lock
Example:
Currently two threads t1,t2, t2 thread stops when T1 adds 5 elements
Example 1:
public class demo1 {@SuppressWarnings ("Rawtypes") private volatile static list list = new arraylist (); @SuppressWarnings ("Unchecked") Public void add () { List.add ("AAA");} Public int size () {return list.size ();} Public static void main (String[] args) {final demo1 demo1 = new demo1 (); Thread t1 = new thread (new runnable () {@Overridepublic void run () {try {for (int i = 0; i < 10; i++) {demo1.add (); System.out.println ("Current thread : " + thread.currentthread (). GetName () + "added an element"); Thread.Sleep (500);}} catch (exception e) {e.printstacktrace ();}}}, "T1"); Thread t2 = new thread (new runnable () {@Overridepublic void run () {while (True) {if (Demo1.size () == 5) &NBSp {System.out.println ("Current thread receives notification : " + thread.currentthread (). GetName () + ", size = 5 thread Stop ... "); Throw new runtimeexception ();}}}}, " T2 "); T1.start (); T2.start ( );}}
Effect:
650) this.width=650; "src=" Https://s4.51cto.com/wyfs02/M02/8E/9B/wKiom1jGl-ShF_G-AACwIKDxnjA659.png "title=" u259y {TU} V9ff7xv7~jzl6e.png "alt=" Wkiom1jgl-shf_g-aacwikdxnja659.png "/>
This is achieved by using the while (true) in the T2 thread, and is improved, such as: Use Wait/notify
public class demo2 {@SuppressWarnings ("Rawtypes") private volatile static list list = new arraylist (); @SuppressWarnings ("Unchecked") Public void add () { List.add ("AAA");} Public int size () {return list.size ();} Public static void main (String[] args) {final object lock = new object (); Final demo2 demo2 = new demo2 (); Thread t1 = new thread (new runnable () {@Overridepublic void run () {try {synchronized (Lock) {for (int i = 0; i < 10; i++) {demo2.add (); System.out.println ("Current thread : " + thread.currentthread (). GetName () + "added an element"); Thread.Sleep (;if ) (Demo2.size () == 5) {system.out.println ("Notify ..."); Lock.notify ();}}} catch (exception e) {e.printstacktrace ();}}},&nbSP; " T1 "); Thread t2 = new thread (new runnable () {@Overridepublic void run () {try {synchronized (Lock) {if (Demo2.size () != 5) {lock.wait ();} System.out.println ("Current thread receives notification : " + thread.currentthread (). GetName () + ", size = 5 thread Stop ... "); Throw new runtimeexception ();}} catch (interruptedexception e) {e.printstacktrace ();}}}, "T2"); T2.start (); T1.start () ;}}
Effect:
650) this.width=650; "src=" Https://s4.51cto.com/wyfs02/M00/8E/9B/wKiom1jGmymBnsE1AACowvkj3qg610.png "title=" B ' $ vgaw4$c4[l0wxhsl4v ' B.png "alt=" Wkiom1jgmymbnse1aacowvkj3qg610.png "/>
Description: A notification was issued when T1 added 5 elements, but notify did not release the lock, so the T2 thread was not able to execute. The disadvantage is not real-time, using Countdownlatch improvement: await ()/countdown ()
public class demo3 {@SuppressWarnings ("Rawtypes") private volatile static list list = new arraylist (); @SuppressWarnings ("Unchecked") Public void add () { List.add ("AAA");} Public int size () {return list.size ();} Public static void main (String[] args) {final countdownlatch cdl = new countdownlatch (1); Final demo3 demo2 = new demo3 (); Thread t1 = new thread (new runnable () {@Overridepublic void run () {try {for (int i = 0; i < 10; i++) {demo2.add (); System.out.println ("Current thread : " + thread.currentthread (). GetName () + "added an element"); Thread.Sleep (;if ) (Demo2.size () == 5) {system.out.println ("Notify ..."); Cdl.countdown ();}} catch (exception e) {e.printstacktrace ();}}}, "T1"); ThreaD t2 = new thread (new runnable () {@Overridepublic void run () {try {if (Demo2.size () != 5) {cdl.await ();} System.out.println ("Current thread receives notification : " + thread.currentthread (). GetName () + ", size = 5 thread Stop ... "); Throw new runtimeexception ();} catch (interruptedexception e) {e.printstacktrace ();}}}, "T2"); T2.start (); T1.start () ;}}
Effect:
650) this.width=650; "src=" Https://s4.51cto.com/wyfs02/M00/8E/99/wKioL1jGngXB46p9AACyvPR3Qm8100.png "title=" i4be~ L15dt2uocq5x2yhn89.png "alt=" Wkiol1jgngxb46p9aacyvpr3qm8100.png "/>
To simulate a queue using wait and notify
Demand:
Analog Blockingqueue: First it is a queue, and it supports blocking mechanisms, blocking of putting in and getting data, implementing simple methods put and take
Put (obj):
Add obj to Blockingqueue, and if Blockingqueue has no space, the thread calling this method is blocked until there is space in the blockingqueue to continue.
Take ():
Take the first data in the Blockingqueue, such as Blockingqueue is empty, then the thread calling this method is blocked until there is data in the Blockingqueue to continue.
The collection of public class demo4 {// elements private linkedlist<object> list = New linkedlist<object> ();// min. length private int minsize = 0;// Length Atomicinteger length = new atomicinteger (0);// Maximum length Private final int maxsize;private final static object lock = new object ();p ublic Demo4 (Int maxsize) {this.maxsize = maxsize;} add Element Public void put (object obj) {synchronized (lock) {if ( Length.get () == this.maxsize) {try {lock.wait ();} catch (interruptedexception e) {e.printstacktrace ();}} List.add (obj); Length.incrementandget (); System.out.println ("Current Thread" + thread.currentthread (). GetName () + "added an element : " + obj); Lock.notifyall ();}} remove Element Public object take () {object obj = null;synchronized (Lock) {if (Length.get () == this.minsize) {try {lock.wait (); catch (interruptedexception e) {e.printstacktrace ();}} Obj = list.removefirst (); Length.decrementandget (); System.out.println ("Current Thread" + thread.currentthread (). GetName () + "out of an element : " + obj); Lock.notifyall ();} Return obj;} Public static void main (String[] args) {final demo4 demo4 = new demo4 (5);d emo4.put ("AA");d emo4.put ("BB");d emo4.put ("cc");d emo4.put ("ee"); New thread (new Runnable () {@Overridepublic void run () {demo4.put ("FF");d emo4.put ("GG");d emo4.put ("hh"); Demo4.put ("II");d emo4.put ("JJ");}}, "T1"). Start (); New thread (new runnable () {@ Overridepublic void run () {demo4.take ();d emo4.take ();}}, "T2"). Start (); New thread (new runnable () {@Overridepublic void run () {demo4.taKe ();d emo4.take ();}}, "T3"). Start ();}}
Effect:
650) this.width=650; "src=" Https://s5.51cto.com/wyfs02/M02/8E/9B/wKiom1jGpSqD73UKAABZy-qKKUQ347.png "title=" 5} LBWRNGS1 (W ' i6nxev38nn.png "alt=" Wkiom1jgpsqd73ukaabzy-qkkuq347.png "/>
Concurrent Programming (7): Communication between Threads wait and notify