Producer and consumer models are ubiquitous in life and describe the relationship between coordination and collaboration. For example, a person is preparing food (producers), while another person is eating (a consumer), they use a common table for placing plates and taking dishes, producers prepare food, and if the table is full, wait for the consumer (that food) to wait if the table is empty. The table here is a shared object. The Java Executor framework itself implements the producer consumer model, which is responsible for adding and executing tasks, respectively.
Advantages of the producer consumer model:
- It simplifies development, you can write the consumer and producer independently or concurrently, it just needs to know who the shared object is;
- Producers do not need to know who the consumer is or how many consumers it is, and the same is true for consumers;
- Producers and consumers can execute at different speeds;
- Separated consumers and producers can write more concise, readable and maintainable code in function;
producer consumer issues in multi-threading
Implement producer consumer design patterns so that producers should wait if the queue or basket is full, the consumer waits if the queue or basket is empty. This problem can be realistic in different ways, the classic method is to use the wait and notify method in the producer and consumer threads to work together, in the queue full or the queue is empty conditions under the condition of blocking, Java5 block Queue (blockingqueue) data structure is simpler, Because it implicitly provides these controls, now you do not need to use wait and nofity to communicate between producers and consumers, and the put () method of the blocking queue will block if the queue is full, the queue take () method will block if the queue is empty.
Implementing producer consumer patterns with blocking queues
The blocking queue implementation of the producer consumer model is super simple, it provides out-of-the-box support blocking method put () and take (), developers do not need to write confused wait-nofity code to achieve communication. Blockingqueue an interface, JAVA5 provides different realities, such as Arrayblockingqueue and Linkedblockingqueue, both of which are in FIFO order. And Arraylinkedqueue is a natural bounded, linkedblockingqueue selectable boundary. Here is an example of a complete producer consumer code that is easier to understand than the traditional wait, nofity code.
The code is as follows:
Public classProducerconsumerpattern { Public Static voidMain (String args[]) {//Creating Shared ObjectBlockingqueue Sharedqueue =NewLinkedblockingqueue (); //Creating Producer and Consumer ThreadThread Prodthread =NewThread (NewProducer (sharedqueue)); Thread Consthread=NewThread (NewConsumer (sharedqueue)); //starting producer and Consumer threadProdthread.start (); Consthread.start (); }} //Producer Class in JavaclassProducerImplementsRunnable {Private FinalBlockingqueue Sharedqueue; PublicProducer (Blockingqueue sharedqueue) { This. Sharedqueue =Sharedqueue; } @Override Public voidrun () { for(inti=0; i<10; i++){ Try{System.out.println ("Produced:" +i); Sharedqueue.put (i); } Catch(Interruptedexception ex) {Logger.getlogger (Producer.class. GetName ()). log (Level.severe,NULL, ex); } } }} //Consumer Class in JavaclassConsumerImplementsrunnable{Private FinalBlockingqueue Sharedqueue; PublicConsumer (Blockingqueue sharedqueue) { This. Sharedqueue =Sharedqueue; } @Override Public voidrun () { while(true){ Try{System.out.println ("Consumed:" +Sharedqueue.take ()); } Catch(Interruptedexception ex) {Logger.getlogger (Consumer.class. GetName ()). log (Level.severe,NULL, ex); } } }}
Producer Consumer Model