Design patterns of producer consumer models of many ways to implement (Java) __ producer Consumers

Source: Internet
Author: User
Tags thread class

Producer consumer problem is one of the classic problems in the research of multithreaded process, it describes a buffer as a storehouse, the producer can put the product into the storehouse, and the consumer can take the product from the storehouse. Solutions to producer/consumer problems can be divided into two categories: (1) adopting a mechanism to protect the synchronization between producers and consumers, and (2) establishing a pipeline between producers and consumers. The first method has higher efficiency, and is easy to implement, the code is better controlled, belongs to the common pattern. The second type of pipeline buffer is not easy to control, the data object is not easy to package and so on, the practicability is not strong. Therefore, this article only describes the implementation of synchronization mechanism of producer/consumer issues.

The core of the synchronization problem is how to ensure the integrity of the same resource being accessed concurrently by multiple threads. A common method of synchronization is to use a signal or locking mechanism to ensure that resources are accessed at most one thread at any time. The Java language implements a full object in multithreaded programming and provides good support for synchronization mechanisms. There are four methods in Java that support synchronization, the first three of which are synchronous methods, and one is the pipe method.

(1) Wait ()/Notify () method

(2) await ()/signal () method

(3) Blockingqueue blocking queue method

(4) Pipedinputstream/pipedoutputstream

This article only introduces the first three kinds of the most commonly used, the fourth kind does not discuss for a while, interested readers can go to the Internet to find the answer.

First, wait ()/Notify () method

The wait ()/nofity () method is two methods of the base class object, which means that all Java classes will have both methods, so that we can implement a synchronization mechanism for any object.

Wait () method: When the buffer is full/empty, the producer/consumer thread stops its execution, discards the lock, keeps itself in the state, and lets the other thread execute.

Notify () method: When the producer/consumer puts/takes out a product to the buffer, it sends an executable notification to the other waiting thread while discarding the lock and putting itself in a waiting state.

Read the text may not be very good understanding, I came to a piece of code to understand:

Import java.util.LinkedList; /** * Warehouse class Storage Implementation Buffer * * email:530025983@qq.com * * @author monkey.  
  
    D.meng 2011-03-15 * */public class Storage {//warehouse maximum storage private final int max_size = 100;  
  
    Warehouse storage of the carrier private linkedlist<object> list = new linkedlist<object> ();  
            Production num products public void produce (int num) {//Sync code snippet synchronized (list) { If the warehouse remaining capacity is not sufficient while (list.size () + num > max_size) {SYSTEM.OUT.P  
                Rintln ("Number of products to be produced": "+ num +"//T "Stock": "+ list.size () +"/"/"/"/"/"/");  
                try {//Because the condition is not satisfied, production blocking list.wait ();  
                catch (Interruptedexception e) {e.printstacktrace ();  }}//Production conditions are met, production num products
            for (int i = 1; I <= num; ++i) {List.add (New Object ());  
  
            System.out.println ("" "has produced the number of products": "+ num +"/t "is the storage volume of": "+ list.size ());  
        List.notifyall ();   
        }//consumption num products public void consume (int num) {//Sync code snippet synchronized (list) {//If warehouse storage is low while (list.size () < num) {Syste  
                M.out.println ("Quantity of products to be consumed": "+ num +"/////"stock": "+ list.size () +"/T temporarily unable to perform production task! ");  
                try {//Because the condition is not satisfied, consumption blocking list.wait ();  
                catch (Interruptedexception e) {e.printstacktrace ();  
            }///Consumption condition is satisfied, consume NUM product for (int i = 1; I <= num ++i)  
         {       List.remove ();  
  
            System.out.println ("" "the number of products already consumed": "+ num +"/t "is the storage volume of": "+ list.size ());  
        List.notifyall ();  
    }//Get/set method public linkedlist<object> GetList () {return list;  
    public void setlist (linkedlist<object> list) {this.list = list;  
    public int getmax_size () {return max_size; }/** * Producer class producer Inherits thread class thread * * email:530025983@qq.com * * * @author monkey.  
  
    D.meng 2011-03-15 * */public class Producer extends Thread {//per production quantity private int num;  
  
    Where the warehouse is placed private Storage Storage;  
    constructor to set the warehouse public Producer (Storage Storage) {this.storage = Storage;  
    }//thread run function public void run () {produce (num);  
    \//Call warehouse storage production function public void produce (int num) {    Storage.produce (num);  
    }//Get/set method public int Getnum () {return num;  
    public void setnum (int num) {this.num = num;  
    Public Storage GetStorage () {return Storage;  
    public void Setstorage (Storage Storage) {this.storage = Storage; /** * Consumer Class consumer Inheritance thread class thread * * email:530025983@qq.com * * * @author monkey.  
  
    D.meng 2011-03-15 * */public class Consumer extends Thread {//per consumption of the number of products private int num;  
  
    Where the warehouse is placed private Storage Storage;  
    constructor to set the warehouse public Consumer (Storage Storage) {this.storage = Storage;  
    }//thread run function public void run () {consume (num);  
    \//Call warehouse storage production function public void consume (int num) {storage.consume (num);  
}//Get/set method public int Getnum () {        return num;  
    public void setnum (int num) {this.num = num;  
    Public Storage GetStorage () {return Storage;  
    public void Setstorage (Storage Storage) {this.storage = Storage; }/** * Testing class Test * * email:530025983@qq.com * * @author monkey.   
        D.meng 2011-03-15 * */public class Test {public static void main (string[] args) {//Warehouse object  
  
        Storage Storage = new Storage ();  
        Producer Object Producer p1 = new Producer (storage);  
        Producer P2 = new Producer (storage);  
        Producer p3 = new Producer (storage);  
        Producer P4 = new Producer (storage);  
        Producer P5 = new Producer (storage);  
        Producer P6 = new Producer (storage);  
  
        Producer P7 = new Producer (storage);  
        Consumer object Consumer C1 = new Consumer (storage);  
  Consumer C2 = new Consumer (storage);      Consumer C3 = New Consumer (storage);  
        Set up the production quantity of producer products P1.setnum (10);  
        P2.setnum (10);  
        P3.setnum (10);  
        P4.setnum (10);  
        P5.setnum (10);  
        P6.setnum (10);  
  
        P7.setnum (80);  
        Set up consumer product consumption quantity C1.setnum (50);  
        C2.setnum (20);  
  
        C3.setnum (30);  
        Thread starts executing c1.start ();  
        C2.start ();  
        C3.start ();  
        P1.start ();  
        P2.start ();  
        P3.start ();  
        P4.start ();  
        P5.start ();  
        P6.start ();  
    P7.start (); } "number of products to consume": 50 "Stock": 0  
Unable to perform production task temporarily! "Quantity of products to be consumed": 30 "Stock": 0  
Unable to perform production task temporarily! "Quantity of products to be consumed": 20 "Stock": 0  
Unable to perform production task temporarily!  
"has produced the number of products": 10 "is the amount of storage for": 10 "the number of products to be consumed": 20 "Inventory": 10 temporarily unable to carry out production tasks!  
"Number of products to be consumed": 30 "Inventory": 10 temporarily unable to carry out production tasks!  
"Number of products to be consumed": 50 "Inventory": 10 temporarily unable to carry out production tasks!  
"has produced the number of products": 10 "is the amount of storage for": 20 "the number of products to be consumed": 50 "Inventory": 20 temporarily unable to carry out production tasks!  
"Number of products to be consumed": 30 "Inventory": 20 temporarily unable to carry out production tasks! "Number of products already consumed": 20    "The current storage quantity is": 0 "already produces the product number": 10 "The current storage quantity is": 10 "already produces the product number": 10 "The present quantity of storage is": 20 "has already produced the product number": 80 "The present quantity of storage is": 100 "the number of products to be produced": 10 "library  
Stock ": 100 temporarily unable to carry out production task!   "Number of products already consumed": 30 "is the amount of storage for": 70 "has been consumed by the number of products": 50 "is the amount of storage for": 20 "has produced the number of products": 10 "is the amount of storage": 30 "has produced the number of products": 10 "The amount of storage is"

After reading the above code, you have an understanding of the synchronization implemented by the Wait ()/Notify () method. You may want to define the public void produce (int num) and the public void consume (int num) in the storage class, and the method is confused, Why not implement these two methods directly in the producer class producer and consumer class consumer, but call the implementation in the storage class? Calm down, the text will have an explanation. Let's go down first.

Ii. await ()/signal () method

After JDK5.0, Java provides more robust threading mechanisms, including synchronization, locking, thread pooling, and so on, which enable finer-grained threading control. await () and signal () are the two methods used to do synchronization, and their functions are essentially the same as wait ()/nofity (), and they are completely replaceable, but they are directly tied to the newly introduced locking mechanism lock and have greater flexibility. By invoking the Newcondition () method on the lock object, bind the condition variable and a lock object to control the security of concurrent programs accessing competing resources. Here's a look at the code:

Import java.util.LinkedList;  
Import java.util.concurrent.locks.Condition;  
Import Java.util.concurrent.locks.Lock;  
  
Import Java.util.concurrent.locks.ReentrantLock; /** * Warehouse class Storage Implementation Buffer * * email:530025983@qq.com * * @author monkey.  
  
    D.meng 2011-03-15 * */public class Storage {//warehouse maximum storage private final int max_size = 100;  
  
    Warehouse storage of the carrier private linkedlist<object> list = new linkedlist<object> ();  
  
    Lock private Final lock lock = new Reentrantlock ();  
  
    Warehouse full condition variable private final Condition fully = Lock.newcondition ();  
  
    Warehouse empty condition variable private final Condition empty = Lock.newcondition ();  
  
        Production num product public void produce (int num) {//Get lock Lock.lock ();  If the warehouse remaining capacity is not sufficient while (list.size () + num > max_size) {System.out.println (number of products to be produced ":"!");  
            try {//Because the condition is not satisfied, production blocking full.await ();  
            catch (Interruptedexception e) {e.printstacktrace (); If the production conditions are met, the production of NUM products for (int i = 1; I <= num ++i) {lis  
        T.add (New Object ());  
  
        System.out.println ("" "has produced the number of products": "+ num +"/t "is the storage volume of": "+ list.size ());  
        Wake up all other threads full.signalall ();  
  
        Empty.signalall ();  
    Release lock Lock.unlock ();  
  
        //consumption num product public void consume (int num) {//Get lock Lock.lock (); If the warehouse storage is insufficient while (List.size () < num) {System.out.println ("" quantity of products to consume: + num +/t  
            "Stock": "+ list.size () +"/t temporarily can not perform the production task! "); try {//Because the condition is not satisfied, consumption blocking emptY.await ();  
            catch (Interruptedexception e) {e.printstacktrace (); }///Consumption condition is satisfied, consume NUM product for (int i = 1; I <= num ++i) {lis  
        T.remove ();  
  
        System.out.println ("" "the number of products already consumed": "+ num +"/t "is the storage volume of": "+ list.size ());  
        Wake up all other threads full.signalall ();  
  
        Empty.signalall ();  
    Release lock Lock.unlock ();  
    }//Set/get method public int getmax_size () {return max_size;  
    Public linkedlist<object> GetList () {return list;  
    public void setlist (linkedlist<object> list) {this.list = list; } "number of products to consume": 50 "Stock": 0  
Unable to perform production task temporarily! "Quantity of products to be consumed": 30 "Stock": 0  
Unable to perform production task temporarily!  
"has produced the number of products": 10 "is the amount of storage for": 10 "has produced the number of products": 10 "is the amount of storage for": 20 "the number of products to be consumed": 50 "Inventory": 20 temporarily can not carry out production tasks! "Quantity of products to be consumed": 30 "stock": 20    Unable to perform production task temporarily!  
"has produced the number of products": 10 "is the amount of storage for": 30 "the number of products to be consumed": 50 "Inventory": 30 temporarily unable to carry out production tasks!  
"The number of products already consumed": 20 "is the amount of storage for": 10 "has produced the number of products": 10 "is the amount of storage for": 20 "the number of products to be consumed": 30 "Inventory": 20 temporarily can not perform production tasks!  
"has produced the number of products": 80 "is the amount of storage for": 100 "to produce the number of products": 10 "inventory": 100 temporarily unable to carry out production tasks!   "Number of products already consumed": 50 "The current storage volume is": 50 "has produced the number of products": 10 "is the amount of storage for": 60 "has been consumed by the number of products": 30 "is the amount of storage": 30 "has been the production of products number": 10 "The amount of storage is"

You only need to update the warehouse class storage code, the producer producer, the consumer consumer, the code that tests class test does not need to make any changes. So we'll know for God's horse I want to define public void produce (int num) in the storage class, and public void consume (int num); And in the producer class producer and consumer class consumer call the implementation of the storage class. Centralize the possible changes in one class without impacting the original architectural design without modifying other business-layer code. Inadvertently, we seem to have used some kind of design pattern, specifically what I forget, ah haha, and so I want to tell you again ~

three, Blockingqueue blocking queue method

Blockingqueue is a new addition to JDK5.0, a queue that has already implemented synchronization internally, using our 2nd await ()/signal () method. It can specify the capacity size when the object is generated. It is used for blocking operations with the put () and take () methods.

Put () method: Similar to our producer thread above, automatic blocking when capacity is maximized.

Take () method: similar to our consumer thread above, the capacity of 0 o'clock, automatic blocking.

About Blockingqueue content on the internet there are a lot of people can search their own, I do not introduce more in this. Look at the code directly below, as usual, we only need to change the warehouse class storage code can:

Import Java.util.concurrent.LinkedBlockingQueue; /** * Warehouse class Storage Implementation Buffer * * email:530025983@qq.com * * @author monkey.  
  
    D.meng 2011-03-15 * */public class Storage {//warehouse maximum storage private final int max_size = 100; Warehouse Storage Carrier Private Linkedblockingqueue<object> list = new Linkedblockingqueue<object> (100  
  
    );  
        Production num product public void produce (int num) {//If warehouse remaining capacity is 0 if (list.size () = = max_size)  
  
        {System.out.println ("inventory": + max_size + "/t temporarily unable to perform production task!");}  
                Produce num for (int i = 1; I <= num ++i) {try {) When production conditions are met  
            Insert the product, automatically block List.put (new Object ());  
            catch (Interruptedexception e) {e.printstacktrace ();  
 } System.out.println ("" Is "": "+ list.size ());       }//consumption num product public void consume (int num) {//If warehouse storage is not sufficient if (list  
        . Size () = = 0) {System.out.println ("inventory": 0/t temporarily unable to perform production tasks!);  
            ///consumption conditions, consumer num products for (int i = 1; I <= num ++i) {try  
            {//Consumer products, automatic blocking list.take ();  
            catch (Interruptedexception e) {e.printstacktrace ();  
    } System.out.println ("" Is "": "+ list.size ());  
    }//Set/get method public linkedblockingqueue<object> GetList () {return list;  
    public void setlist (linkedblockingqueue<object> list) {this.list = list;  
    public int getmax_size () {return max_size; } "Inventory": 0  
Unable to perform production task temporarily! "Inventory": 0  
Unable to perform production task temporarily! "Warehouse quantity is": 1 "now warehousing quantity is": 1 "nowStorage volume is ": 3" is the storage quantity is ": 4" The present quantity of storage is: 5 "Now warehousing quantity is": 6 "is the warehouse quantity is": 7 "is the warehouse quantity is": 8 "The present warehousing quantity is": 9 "The present warehousing quantity is": 10 "The present warehousing quantity is": 11 "The present warehousing quantity is": 1 "is Storage volume is ": 2" is the storage quantity is ": 13" The present quantity of storage is: 14 "Now warehousing quantity is": 17 "is the warehouse quantity is": 19 "is the warehouse quantity is": 20 "The present warehousing quantity is": 21 "The present warehousing quantity is": 22 "The present warehousing quantity is": 23 "The present warehousing quantity is": 24 "The current storage quantity is": 25 "The present storage quantity is": 26 "The present storage quantity is": 12 "now warehousing quantity is": 1 "is the warehouse quantity is": 1 "The present warehousing quantity is": 2 "The present warehousing quantity is": 3 "The present warehousing quantity is": 4 "The present warehousing quantity is": 5 "The present warehousing quantity is ": 6" is the warehouse quantity is ": 7" is the warehouse quantity is ": 27" The present quantity of storage is ": 8" now warehousing quantity is ": 6" is the warehouse quantity is ": 18" The present warehousing quantity is ": 2" The present warehousing quantity is ": 3" The present warehousing quantity is ": 4" The present warehousing quantity is ": 5" The present warehousing quantity is ": 6" is the warehouse quantity is ": 7" The present quantity of storage is ": 8" now warehousing quantity is ": 9" is the warehouse quantity is ": 10" is the warehouse quantity is ": 16" The present warehousing quantity is ": 11" The present warehousing quantity is ": 12" The present warehousing quantity is ": 13" The present warehousing quantity is ": 14" is Storage volume is ": 15" is the storage quantity is ": 1" The present quantity of storage is: 2 "now warehousing quantity is": 3 "is the warehouse quantity is": 3 "is the warehouse quantity is": 15 "The present warehousing quantity is": 1 "The present warehousing quantity is": 0 "The present warehousing quantity is": 1 "The present warehousing quantity is": 1 "is Storage quantity is ": 1" is the warehouse quantity is ": 2" is the storage quantity is ": 3" The present storage quantity is ": 4" The current storage quantity is ": 0" is the warehouse quantity is ": 1" The present warehousing quantity is ": 5" The present warehousing quantity is ": 6" The present warehousing quantity is ": 7" The present warehousing quantity is ": 8" is the warehousing  
Quantity is ": 9" is the amount of storage for ": 10" is the amount of storage: 11 "Now Warehousing quantity is": 12 "is the warehouse quantity is": 13 "The present warehousing quantity is": 14 "The present warehousing quantity is": 15 "The present warehousing quantity is": 16 "The present warehousing quantity is": 17 "The present warehousing quantity is": 1 "Current Storage quantity is": 1 "The present storage quantity is": 2 
"The current storage volume is": 3 "is the warehouse quantity is": 4 "The present storage quantity is": 5 "Now warehousing quantity is": 6 "is the warehouse quantity is": 3 "The present warehousing quantity is": 3 "The present warehousing quantity is": 1 "The present warehousing quantity is": 2 "The present warehousing quantity is": 3 "The present warehousing quantity is": 4   
"The current storage volume is": 5 "is the warehouse quantity is": 6 "The present storage quantity is": 7 "Now warehousing quantity is": 8 "is the warehouse quantity is": 9 "The present warehousing quantity is": 10 "The present warehousing quantity is": 11 "The present warehousing quantity is": 12 "The present warehousing quantity is": 13 "The present warehousing quantity is": 14 "The current storage volume is": 15 "is the warehouse quantity is": 16 "The present storage quantity is": 17 "now warehousing quantity is": 18 "is the warehouse quantity is": 19 "The present warehousing quantity is": 6 "The present warehousing quantity is": 7 "The present warehousing quantity is": 8 "The present warehousing quantity is": 9 "The present warehousing quantity is  
": 10" is the warehouse quantity is ": 11" The present quantity of storage is ": 12" now warehousing quantity is ": 13" is the warehouse quantity is ": 14" The present warehousing quantity is ": 15" The present warehousing quantity is ": 16" The present warehousing quantity is ": 17" The present warehousing quantity is ": 18" The present warehousing quantity is ": 19 "The current storage volume is": 20 "is the warehouse quantity is": 21 "The present storage quantity is": 22 "The current storage quantity is": 23 "is the warehouse quantity is": 24 "The present warehousing quantity is": 25 "The present warehousing quantity is": 26 "The present warehousing quantity is": 27 "The present warehousing quantity is": 28 "the present storehouse Reserves for ": 29" is the amount of storage for ": 30" is the amount of storage: 31 "Now warehousing quantity is": 32 "is the warehouse quantity is": 33 "is the warehouse quantity is": 34 "The present warehousing quantity is": 35 "The present warehousing quantity is": 36 "The present warehousing quantity is": 37 "The present warehousing quantity is":   38 "The current storage quantity is": 39 "The present storage quantity is": 40

Of course, you'll find that at this point for public void produce (int num); and public void consume (int num); Method business logic implementation is not quite the same as the previous two examples, okay, This example is only to illustrate the use of blockingqueue blocking queues.

Sometimes the put () and System.out.println () output mismatches are possible with blockingqueue because there is no synchronization between them. When the buffer is full, the producer invokes the await () inside the Put () method, discards the execution of the thread, then executes the consumer thread, calls the Take () method, take () internally calls the signal () method, notifies the producer that the thread can execute, The producer's println () is executed before the consumer's println () has been run, so there is an output mismatch.

For Blockingqueue you can rest assured that this is not a problem, it is just a problem with the synchronization between other objects.

The Java implementation of producer/consumer issues is summed up in this




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.