Java Multi-Threading 14: Producer/consumer model

Source: Internet
Author: User

What is a producer/consumer model

An important model, based on the wait/notification mechanism. The producer/consumer model describes a buffer as a warehouse where producers can place products in warehouses where consumers can remove products from the warehouse, and the producer/consumer model is concerned with the following points:

1, producers when the production of consumers can not spend

2, consumer consumption when the producers can not produce

3, buffer space when consumers can not spend

4. Producers cannot produce when the buffer is full

Producer/model as an important model, its advantages are:

1, decoupling. Because there is a buffer, so producers and consumers do not directly call each other, it is easy to think, so that the producer and consumer code changes, will not affect the other side, so that in fact, the strong coupling between producers and consumers to unlock, into the producer and buffer/ Weak coupling between consumer and buffer

2, by balancing the processing capacity of producers and consumers to improve the overall speed of processing data , this is the producer/consumer model is the most important advantage. If the consumer takes the data directly from the producer, if the producer is slow to produce, but the consumer consumes quickly, then the consumer will have to occupy the CPU of the time slice in vain wait over there. With the producer/consumer model, producers and consumers are two separate concurrent bodies, producers of the production of data into the buffer is good, do not have to control consumers, consumers also, from the buffer to take the data is good, do not have to control the producers, the buffer is full of production, the buffer empty will not consume, so that producers/ Consumer's ability to deal with a dynamic balance

Implement producer/consumer models with Wait ()/notify ()

Since the producer/consumer model has a buffer, then we make a buffer for ourselves, and the producers and consumers communicate through this buffer. Value is "" means the buffer is empty, value does not "" means the buffer is full:

Class valueobject{    static String value = "";}

Next is a producer, if the buffer is full, then wait (), no longer production, waiting for the consumer to complete the notification; If the buffer is empty, then the production data into the buffer

PublicClassproducer{PrivateObject lock;Public Producer (Object lock) {this.lock = lock; } public void SetValue ( {try {synchronized< Span style= "color: #000000;" > (lock) {if (! ValueObject.value.equals (" System.nanotime (); System.out.println (the value of set is: "+ value); Valueobject.value =catch (Interruptedexception e) {e.printstacktrace ();}}}  

The consumer is similar, if the buffer is empty, then no longer consumes, wait () waits, waits for the producer to produce the notification, if the buffer is not empty, then go to fetch the data:

PublicClasscustomer{Private Object lock; public Customer (Object lock) { this.lock = lock;} public void GetValue () {try {synchronized< Span style= "color: #000000;" > (lock) {if (ValueObject.value.equals (" Valueobject.value); Valueobject.value = "; Lock.notify (); }} catch (Interruptedexception e) {e.printstacktrace () ; } }} 

Write a main function, open two threads call producer inside the GetValue () method and the customer () inside the SetValue () method:

PublicStaticvoidMain (string[] args) {Object lock =NewObject ();Final Producer Producer =NewProducer (lock);Final Customer customer =NewCustomer (lock); Runnable producerrunnable =NewRunnable () {public void run () { Span style= "color: #0000ff;" >while (truenew Runnable () {public void run () {truenew thread (producerrunnable); Thread customerthread = new thread (customerrunnable); Producerthread.start (); Customerthread.start ();}              

Look at the results of the operation:

... The value of set is: The value of 1444025677743_162366875965845get is: The value of 1444025677743_162366875965845set is: 1444025677743_ The value of 162366875983541Get is: The value of 1444025677743_162366875983541set is: 1444025677743_162366876004776get value is: 1444025677743_ 162366876004776 ...

Production data and consumption data must be in pairs appear, the production of a consumption, full of non-production, empty not consumption, producers can not unlimited production, consumers can not unlimited consumption, in line with the producer/consumer model. The producer is fast, does not occupy the CPU time slice, waits for the consumer to consume to inform it to continue to produce, this piece of time can be used for other threads.

Using await ()/signal () to implement producer and consumer models

, define a buffer first:

Class valueobject{    static String value = "";}

In a different way, the production and consumption methods are placed in a class:

PublicClass ThreadDomain41Extendsreentrantlock{Private Condition Condition =Newcondition ();PublicvoidSet () {Try{lock ();while (! "" ". Equals (Valueobject.value)) condition.await (); Valueobject.value = "123"; System.out.println (Thread.CurrentThread (). GetName () + "produced value, the current value of value is" +Valueobject.value); Condition.signal (); }Catch (Interruptedexception e) {e.printstacktrace ();} finally {unlock ();}} public void get () { Span style= "color: #0000ff;" >try {lock (); while (".equals (Valueobject.value)) condition.await (); Valueobject.value = "; System.out.println (Thread.CurrentThread (). GetName () + "consumes value, and the current value for value is" +catch (Interruptedexception e) {e.printstacktrace ();} finally     

Similarly, open two threads, one thread calls the set () method for production, and the other thread calls the Get () method to consume:

PublicStaticvoidMain (string[] args) {Final ThreadDomain41 td =NewThreadDomain41 (); Runnable producerrunnable =NewRunnable () {PublicvoidRun () {for (int i = 0; i < Integer.max_value; i++) Td.set (); } }; Runnable customerrunnable = new Runnable () { public void Run () {for (int i = 0; i < intege R.max_value; i++) Td.get (); } }; Thread producerthread = new thread (producerrunnable); Producerthread.setname ("Producer"); Thread consumerthread = new thread (customerrunnable); Consumerthread.setname ("Consumer"); Producerthread.start (); Consumerthread.start ();}              

Look at the results of the operation:

... Producer produced value, the current value is 123Consumer consumption of value, value of the current value is producer produced value, value of the current value is 123Consumer consumption of value, The current value of value is producer produced value, the current value of value is 123Consumer consumes value, the current value of value is ...

Same as the Wait ()/notify () mechanism, as well as with the producer/consumer model

Beware of suspended animation

The producer/consumer model ultimately achieves the goal of balancing the processing capacity of producers and consumers , and does not require only one producer and one consumer in the process of achieving this goal. Multiple producers can correspond to multiple consumers, one producer can correspond to a consumer, and multiple producers can correspond to one consumer.

Suspended animation occurs in three of the above scenarios. Theoretical analysis can explain the problem, so you do not write code. Code to write is also very simple, the above two examples casually modify one, open a producer thread/multiple consumer threads, open multiple producer threads/consumer threads, open multiple producer threads/multiple consumer threads can be. Suspended animation refers to all the threads have entered the waiting state, then the program will no longer perform any business functions, the entire project is stuck.

For example, there are producer A and producer B, the buffer is empty and the consumer is waiting. Producer B is in waiting, producer A is informed by the consumer production, producer a produced products should inform consumers, the results inform the producer B, producer B was awakened, found that the buffer is full, so continue to waiting. At this point, two producers of threads in waiting, consumers in waiting, the system suspended animation.

The above analysis can be seen that the reason for the occurrence of suspended animation is because notify is similar, so non-single-producer/single-consumer scenarios, can take two methods to solve the problem:

1. Synchronized wakes all threads with Notifyall (), Reentrantlock wakes all threads with Signalall ()

2, with Reentrantlock definition two condition, a producer of condition, a consumer condition, wake up call the corresponding condition signal () method can be

Java Multi-Threading 14: Producer/consumer model

Related Article

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.