1 single-producer single-Consumer
Packageexample;classresource{PrivateString name; Private intNum=1; Private Booleanflag=false; Public synchronized voidset (String name) {if(flag) {Try{wait (); } Catch(interruptedexception e) {//TODO Auto-generated catch blockE.printstacktrace (); } } This. name=name+num; Num++; System.out.println (Thread.CurrentThread (). GetName ()+ "Production" + This. Name); Flag=true; Notify (); } Public synchronized voidout () {if(!flag) { Try{wait (); } Catch(interruptedexception e) {//TODO Auto-generated catch blockE.printstacktrace (); }} System.out.println (Thread.CurrentThread (). GetName ()+ "Consumption" + This. Name); Flag=false; Notify (); }}classProducerImplementsrunnable{PrivateResource R; Producer (Resource r) { This. r=R; } Public voidrun () { while(true) {R.set (Bread); } } }classConsumerImplementsrunnable{PrivateResource R; Consumer (Resource r) { This. r=R; } Public voidrun () { while(true) {r.out (); } } } Public classtest{ Public Static voidMain (string[] args) {Resource R=NewResource (); Producer Pro=NewProducer (R); Consumer Con=NewConsumer (R); Thread T1=NewThread (PRO); Thread T2=NewThread (con); T1.start (); T2.start (); }}
Thread-0 Production of bread 1
Thread-1 Consumption Bread 1
Thread-0 Production of bread 2
Thread-1 Consumption Bread 2
Thread-0 Production of bread 3
Thread-1 Consumption Bread 3
Thread-0 Production of bread 4
Thread-1 Consumption Bread 4
Thread-0 Production of bread 5
Thread-1 Consumption Bread 5
Thread-0 Production of bread 6
Thread-1 Consumption Bread 6
Thread-0 Production of bread 7
Thread-1 Consumption Bread 7
Thread-0 Production of bread 8
Thread-1 Consumption Bread 8
Thread-0 Production of bread 9
Thread-1 Consumption Bread 9
Thread-0 Production of bread 10
Thread-1 Consumption Bread 10
Thread-0 Production of Bread 11
.........................
2 Multi-producer and multi-consumer models
Packageexample;classresource{PrivateString name; Private intNum=1; Private Booleanflag=false; Public synchronized voidset (String name) { while(flag) {Try{wait (); } Catch(interruptedexception e) {//TODO Auto-generated catch blockE.printstacktrace (); } } This. name=name+num; Num++; System.out.println (Thread.CurrentThread (). GetName ()+ "Production" + This. Name); Flag=true; Notifyall (); } Public synchronized voidout () { while(!flag) {//change if to while Try{wait (); } Catch(interruptedexception e) {//TODO Auto-generated catch blockE.printstacktrace (); }} System.out.println (Thread.CurrentThread (). GetName ()+ "Consumption" + This. Name); Flag=false; Notifyall (); //Change to Notifyall () }}classProducerImplementsrunnable{PrivateResource R; Producer (Resource r) { This. r=R; } Public voidrun () { while(true) {R.set (Bread); } } }classConsumerImplementsrunnable{PrivateResource R; Consumer (Resource r) { This. r=R; } Public voidrun () { while(true) {r.out (); } } } Public classtest{ Public Static voidMain (string[] args) {Resource R=NewResource (); Producer Pro=NewProducer (R); Consumer Con=NewConsumer (R); Thread T1=NewThread (PRO); Thread T2=NewThread (PRO); Thread T3=NewThread (con); Thread T4=NewThread (con); T1.start (); T2.start (); T3.start (); T4.start (); }}
Here we have made two changes, the main reason is 2 points.
1. If there is a security problem with if and notify ()
Public synchronized voidset (String name) {if(flag) {//2,t0 Once again obtains execution right, after judgment wait (), then the production line T1 obtains the execution right, after judgment wait ()Try{wait (); 6,t0 get executive right, and produce bread 2, wake up T2, release lock}Catch(interruptedexception e) {//TODO Auto-generated catch blockE.printstacktrace (); } } This. name=name+num; Num++; System.out.println (Thread.CurrentThread (). GetName ()+ "Production" + This. Name); 1, production line t0 produce bread 1, flag is true flag=true; Notify (); } Public synchronized voidout () {if(!flag) {//5 consumer thread t3 get execution and lock, Wait (), release lock Try{wait (); 7,t2 wakes up and consumes bread 2, wakes t3,t3 and consumes bread 2}Catch(interruptedexception e) {//TODO Auto-generated catch blockE.printstacktrace (); }} System.out.println (Thread.CurrentThread (). GetName ()+ "Consumption" + This. Name); 3 Consumer thread T2 get executive right to consume T1 flag=false; Notify (); 4 Wake t0, but T0 is not locked,flag=false; }
The biggest problem is if (), the thread wakes up and doesn't have to Judge flag anymore.
2 If you use while plus notify (), you may cause a deadlock. So with Notifyall ()
Multi-producer and multi-consumer issues