Simulating consumer and subscriber patterns through threading:
First of all, define a clerk: The clerk includes the purchase and sale method; Second, define a producer and producer to produce products for the clerk; Moreover, define a consumer who is responsible for consuming products from shop assistants.
Clerk:
/*** Shop assistant*/classClerk {Private intProduct = 0; /*** Arrival*/ Public synchronized voidpurchase () {if(Product >= 10) {System.out.println ("The product is full ... "); } Else{System.out.println (Thread.CurrentThread (). GetName ()+ ":" + ++product); } } /*** Sell Goods*/ Public synchronized voidSell () {if(Product <= 0) {System.out.println ("Product shortage ... "); } Else{System.out.println (Thread.CurrentThread (). GetName ()+ ":" + --product); } }}
Producers
/***/classimplements runnable{private Clerk Clerk; Public Productor (Clerk clerk) { this. clerk=clerk; } Public void run () { for (int i=0;i<20;i++) { clerk.purchase (); }}}
Consumers
/***/classimplements runnable{private Clerk Clerk; Public Consumer (Clerk clerk) { this. clerk=clerk; } Public void run () { for (int i=0;i<20;i++) { Clerk.sell (); }}}
At this point, run the program and run the following results:
Productor-a:1Productor-a:2Productor-a:3Productor-a:4Productor-a:5Productor-a:6Productor-a:7Productor-a:8Productor-a:9Productor-a:10product is full ... Product is full ... Product is full ... Product is full ... Product is full ... Product is full ... Product is full ... Product is full ... Product is full ... Product is full ... Consumer-a:9Consumer-a:8Consumer-a:7Consumer-a:6Consumer-a:5Consumer-a:4Consumer-a:3Consumer-a:2Consumer-a:1Consumer-a:0Product shortage ... Product shortage ... Product shortage ... Product shortage ... Product shortage ... Product shortage ... Product shortage ... Product shortage ... Product shortage ... Product shortage ...
There are two problems that can be found here from running print results:
1) Once the producer discovers that the clerk's product is full, it still does not stop the production of the product, and continuously produces the product;
2) Once the consumer finds out that the clerk's product is out of stock, it continues to consume.
Here is obviously flawed, in reality should be: once the goods are found to be full, it is not in the purchase, but open the act of selling goods, when cargo behavior found no goods, the beginning of the purchase behavior.
Improved for producer consumers:
The consumer, the producer, the client calls the code unchanged, only modifies the Clerk class:
/*** Shop assistant*/classClerk {Private intProduct = 0; /*** Arrival*/ Public synchronized voidpurchase () {if(Product >= 10) {System.out.println ("The product is full ... "); Try { This. Wait (); } Catch(interruptedexception e) {e.printstacktrace (); } } Else{System.out.println (Thread.CurrentThread (). GetName ()+ ":" + ++product); This. Notifyall (); } } /*** Sell Goods*/ Public synchronized voidSell () {if(Product <= 0) {System.out.println ("Product shortage ... "); Try { This. Wait (); } Catch(interruptedexception e) {e.printstacktrace (); } } Else{System.out.println (Thread.CurrentThread (). GetName ()+ ":" + --product); This. Notifyall (); } }}
At this point the result is running:
Productor-a:1Consumer-a:0Product shortage ... Productor-a:1Productor-a:2Productor-a:3Productor-a:4Productor-a:5Productor-a:6Productor-a:7Productor-a:8Productor-a:9Productor-a:10product is full ... Consumer-a:9Consumer-a:8Consumer-a:7Consumer-a:6Consumer-a:5Consumer-a:4Consumer-a:3Consumer-a:2Consumer-a:1Consumer-a:0Product shortage ... Productor-a:1Productor-a:2Productor-a:3Productor-a:4Productor-a:5Productor-a:6Productor-a:7Productor-a:8Consumer-a:7Consumer-a:6Consumer-a:5Consumer-a:4Consumer-a:3Consumer-a:2Consumer-a:1
At this point, the result is running in accordance with the results we want.
Improvement brings problem one:
Modify the maximum number of store clerk class of 1, the producer of one production 20 modified to 2, the consumer 20 also changed to 2.
Clerk class:
/*** Shop assistant*/classClerk {Private intProduct = 0; /*** Arrival*/ Public synchronized voidpurchase () {if(Product >= 1) {System.out.println ("The product is full ... "); Try { This. Wait (); } Catch(interruptedexception e) {e.printstacktrace (); } } Else{System.out.println (Thread.CurrentThread (). GetName ()+ ":" + ++product); This. Notifyall (); } } /*** Sell Goods*/ Public synchronized voidSell () {if(Product <= 0) {System.out.println ("Product shortage ... "); Try { This. Wait (); } Catch(interruptedexception e) {e.printstacktrace (); } } Else{System.out.println (Thread.CurrentThread (). GetName ()+ ":" + --product); This. Notifyall (); } }}
At this point the result is running:
From the running results, the program is a deadlock phenomenon.
Why is there a deadlock problem?
From the running results of the analysis:
The improvement brings problem two:
Java-juc (eight): Use Wait,notify|notifyall to complete producer consumer communication, false wakeup (spurious wakeups) problem scenario, and problem resolution.