Java Producer-Consumer

Source: Internet
Author: User

(a), the problem of the lead


There is a data storage space, divided into two parts, one for storing the person's name, and the other for storing the person's gender;

Our application consists of two threads, one thread keeps adding data (producers) to the data storage space, and the other thread pulls the data out of the data space (consumer);

Because of the thread uncertainty, there are two scenarios:
1. if the producer Line Cheng Gang adds a person's name to the storage space without adding a person's gender, the CPU switches to the consumer thread, and the consumer thread ties the name to the gender of the previous person ;
2. producers put a number of data, consumers began to take data, or consumers to complete a data, not wait until the producers put new data, but also repeated to take out the data that has been taken ;


/** * Analog Data region * */class person{private string name;private string Sex;public string GetName () {return name;} public void SetName (String name) {this.name = name;} Public String Getsex () {return sex;} public void Setsex (String sex) {this.sex = sex;}} /** * Producer */class Producer implements runnable{private person p;public Producer (person p) {this.p = P;} public void Run () {for (int i = 0; i < i++) {if (i% 2== 0) {p.setname ("eldest brother"); try {thread.sleep (2);} catch (Interrupt Edexception e) {e.printstacktrace ();} P.setsex ("Male");} Else{p.setname ("Miss"); try {thread.sleep (5);} catch (Interruptedexception e) {e.printstacktrace ();} P.setsex ("female");}}} Class Consumer implements Runnable{private person p;public Consumer (person p) {this.p = P;} public void Run () {for (int i = 0; i <; i++) {String name = P.getname (); String sex = P.getsex (); System.out.println (name+ "--" + Sex);}}} public class Producer_consumerdemo {public static void main (string[] args) {person p = new person (); New Thread (New produce R (P)). Start (); New Thread (New Consumer (p)). Start ();}} 


On the machine running the above program, the results of the problem can be seen. The results of each run are different, but the results are problematic.

The following code is a solution to the above program problem. Of course, that's the solution: 1. if the producer Line Cheng Gang adds a person's name to the storage space without adding a person's gender, the CPU switches to the consumer thread, and the consumer thread links the name to the gender of the previous person ;2. producers put a number of data, consumers began to take data, or consumers to complete a data, not wait until the producers put new data, but also repeated to take out the data that has been taken ;

Only, question 1 is reflected in this case of gender confusion. Question 2 is reflected in this example of "eldest brother----male" and "Miss----Woman" is not in accordance with our program design alternately appear (production consumption).

See the improvement Code:

/** * Analog data storage area * *//* * Set name and gender synchronization complete, */class person {private string Name;private string sex;//indicates whether the storage area is empty. The store is empty, the consumer stops consuming, the producer works; The store is not empty, the producer stops producing, the consumer begins to consume private Boolean empty = boolean.true;/*** producer (name, gender) * */public void Set (string name, string sex) {synchronized (this) {//if (Empty) while (! Empty.equals (Boolean.true)) {//zone is not empty//the producer should stop waiting for the consumer to "consume" try {this.wait ();//wait for consumer consumption} catch (Interruptedexception E ) {e.printstacktrace ();}} THIS.name = Name;//this.sex = sex;//producer After production, the state of the storage area should be modified to show that its storage space has products available for "consumption" empty = boolean.false;//not empty this.notify ();// Wake up the consumer up "consumption" can be understood as reading storage space in the data}}/** * Consumer consumption (name, gender) */public void get () {synchronized (this) {//Storage area is empty while (! Empty.equals (Boolean.false)) {try {this.wait ();//wait for producer to produce} catch (Interruptedexception e) {e.printstacktrace ();}} String name = GetName (); String sex = Getsex (); SYSTEM.OUT.PRINTLN (name + "+" + sex);//consumption completed, the state of the storage area should be modified empty = boolean.true;//empty this.notify ();//wake-up producer}}public St Ring GetName () {return name;} public void SetName (StringName) {this.name = name;} Public String Getsex () {return sex;} public void Setsex (String sex) {this.sex = sex;}} /** * Producer */class Producer implements Runnable {private person p;public Producer (person p) {this.p = P;} public void Run () {for (int i = 0; i <, i++) {if (i% 2 = = 0) {p.set ("eldest brother", "male"),} else {P.set ("Miss", "female");}}} Class Consumer implements Runnable {private person p;public Consumer (person p) {this.p = P;} public void Run () {for (int i = 0; i <; i++) {P.get ();}}}        public class Producer_consumerdemo {public static void main (string[] args) {person p = new person (); Add the following words to the equivalent of two producers of two consumer//new thread (new Producer (p)). Start ();//new Thread (New Consumer (p)). Start (); New Thread (New Producer (P)). Start (); New Thread (New Consumer (p)). Start ();}}
</pre><pre name= "code" class= "java" ><span style= "White-space:pre" ></span>

Program results:

Big Brother-to-man
Lady-to-woman
Big Brother-to-man
Lady-to-woman

..................

Attention:

Wait (): Let the current thread discard the monitor and wait until other threads call the same monitor and call notify () or Notifyall ().
Notify (): Wakes the first thread that calls the wait method in the same object listener.
Notifyall (): Wakes all threads that call the wait method in the same object listener.

Wait (), notify (), Notifyall (), these three methods belong to object that do not belong to Thread, and these three methods must be called by the synchronization monitor object, in two cases:

1.synchronized modified method, because the default instance of the class (this) is the synchronization monitor, so you can call these three methods in a synchronous method;
2.synchronized modified synchronization code block, the synchronization monitor is the object in parentheses, so you must use this object (Synchronization monitor) to call these three methods;



But here's the problem: if we use a lock object to ensure synchronization, there is no implicit synchronization monitor object in the system, then you can not use three methods, what should be?

Workaround:

Lock instead of synchronous method or synchronous code block, use condition to replace the function of synchronous monitor;
The condition object is created by the Newcondition () method of the lock object;
The methods include :
Await (): The Wait () method equivalent to the synchronization listener;
Signal (): the Notify () method equivalent to the synchronous listener;
Signalall (): The Notifyall () method equivalent to the synchronous listener;


See the following code for specific implementations:


Import Java.util.concurrent.locks.condition;import java.util.concurrent.locks.reentrantlock;/** * Analog Data area * * Can re-enter the lock is not synchronized listener object, how to do?  * * Lock replaces the use of the Synchronized method and the statement, Condition replaces the use of the Object monitor method. */class Person {//create Reentrant Lock object Private final Reentrantlock lock = new Reentrantlock ();p rivate final Condition con = lock.new Condition ();p rivate string Name;private string sex;//indicates whether the storage area is empty private Boolean empty = boolean.true;/** * Production * */public void set (string name, string sex) {Lock.lock (); while (! Empty.equals (Boolean.true)) {//indicates a non-empty state try {con.await ();} catch (Interruptedexception e) {e.printstacktrace ();}} try {this.name = name; Thread.Sleep (1); this.sex = Sex;isempty = Boolean.false;con.signal ();} catch (Interruptedexception e) {e.printstacktrace ();} finally {Lock.unlock ();}} /** * consume */public void get () {lock.lock (); Empty.equals (Boolean.false)) {//Storage area is empty, consumer should wait for try {con.await ();} catch (Interruptedexception e) {e.printstacktrace () ;}} try {String name = GetName (); String sex = Getsex (); System.oUT.PRINTLN (name +--+ + sex);//empty = Boolean.true;con.signal ();} finally {Lock.unlock ();}} Public String GetName () {return name;} public void SetName (String name) {this.name = name;} Public String Getsex () {return sex;} public void Setsex (String sex) {this.sex = sex;}} /** * Producer */class Producer implements Runnable {private person p;public Producer (person p) {this.p = P;} public void Run () {for (int i = 0; i <, i++) {if (i% 2 = = 0) {p.set ("eldest brother", "male"),} else {P.set ("Miss", "female");}}} Class Consumer implements Runnable {private person p;public Consumer (person p) {this.p = P;} public void Run () {for (int i = 0; i <; i++) {P.get ();}}} public class Producer_consumerdemo {public static void main (string[] args) {person p = new person (); New Thread (New produce R (P)). Start (); New Thread (New Consumer (p)). Start ();}}

Program results:

Big Brother-to-man
Lady-to-woman
Big Brother-to-man
Lady-to-woman

..................

Java Producer-Consumer

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.