Objective:
Because of the time relationship before, the "producer consumer problem" is not introduced in the blog essay, so this article as a supplement to the previous "multithreading" article.
Concept :
Producer Consumer issues (Bounded-buffer problem), is a classic case of multithreading synchronization issues. In this case, the main implementation is two roles to coordinate access to the same resource. The primary role of the producer is to generate a certain amount of data into the buffer, and then repeat the process. At the same time, consumers consume the data in buffers. The key to this issue is to ensure that producers do not add data when the buffer is full, and consumers do not consume data when the buffer is empty .
Design : an example has been described in the previous article on multithreading in this blog. The idea is similar to the previous one, but this time a queue of storage resources is introduced, and 2 conditions (Condition) are required for signal transmission. The implementation process is shown in the following diagram:
Code Implementation :
Package Com.gdufe.thread.consumer;import Java.util.concurrent.executorservice;import Java.util.concurrent.executors;import Java.util.concurrent.locks.condition;import Java.util.concurrent.locks.lock;import Java.util.concurrent.locks.reentrantlock;public class ConsumerProducer { private static Buffer buffer = new buffer (); public static void Main (string[] args) {//Create a thread pool with threads executorservice executor = Executo Rs.newfixedthreadpool (2); Executor.execute (New Producertask ()); Executor.execute (New Consumertask ()); Executor.shutdown (); }//A task for adding an int to the buffer private static class Producertask implements Runnable {public void run () {try {int i = 1; while (true) {System.out.println ("Producer writes" + i); Buffer.write (i++); Add a value to the buffer//Put the thread into Sleep thread.sleep ((int) (Math.random () * 10000)); }} catch (InterruptedexceptioN ex) {ex.printstacktrace (); }}}//A task for reading and deleting an int from the buffer private static class Consumertask implements RUNNABL e {public void run () {try {while (true) {System.out.println ("\t\t\tconsumer reads" + BUFFER.R EAD ()); Put the thread into Sleep thread.sleep ((int) (Math.random () * 10000)); }} catch (Interruptedexception ex) {ex.printstacktrace (); }}}//inner class for buffer private static class buffer {private static final int capacity = 1;//Buffer Size private Java.util.linkedlist<integer> queue = new java.util.linkedlist<integer> ();//queue for St Oring Data//Create a new lock private static lock lock = new Reentrantlock (); Create the conditions private static Condition Notempty = Lock.newcondition (); private static Condition Notfull = Lock.newcondition (); public void write (int value) {lock.lock (); Acquire the lock try {while (queue.size () = = capacity) {System.out.println ("Wait for Notfull Condi tion "); Notfull.await (); } queue.offer (value); Notempty.signal (); Signal notempty Condition} catch (Interruptedexception ex) {ex.printstacktrace (); } finally {Lock.unlock ();//Release The Lock}} public int read () {int value = 0; Lock.lock (); Acquire the lock try {while (Queue.isempty ()) {System.out.println ("\t\t\twait for Notempty Condi tion "); Notempty.await (); } value = Queue.remove (); Notfull.signal (); Signal notfull Condition} catch (Interruptedexception ex) {ex.printstacktrace (); } finally {Lock.unlock ();//Release the lock return value; } } }}
Test Results :
Add :
In the Java collection framework, there is a " blocking queue " concept. It features synchronous methods, that is, to apply blocking queues, and we can also implement thread synchronization issues for producer consumers by simplifying the code above.
The reference code is as follows:
1 PackageCom.gdufe.thread.consumer;2 3 ImportJava.util.concurrent.ArrayBlockingQueue;4 ImportJava.util.concurrent.ExecutorService;5 Importjava.util.concurrent.Executors;6 7 Public classConsumerproducerusingblockingqueue {8 Private Staticarrayblockingqueue<integer> buffer =9 NewArrayblockingqueue<integer> (2);Ten One Public Static voidMain (string[] args) { A //Create a thread pool with a threads -Executorservice executor = Executors.newfixedthreadpool (2); -Executor.execute (NewProducertask ()); theExecutor.execute (NewConsumertask ()); - Executor.shutdown (); - } - + //A task for adding an int to the buffer - Private Static classProducertaskImplementsRunnable { + Public voidrun () { A Try { at inti = 1; - while(true) { -SYSTEM.OUT.PRINTLN ("Producer writes" +i); -Buffer.put (i++);//Add Any value to the buffer, say, 1 - //Put the thread into sleep -Thread.Sleep ((int) (Math.random () * 10000)); in } -}Catch(Interruptedexception ex) { to ex.printstacktrace (); + } - } the } * $ //A task for reading and deleting an int from the bufferPanax Notoginseng Private Static classConsumertaskImplementsRunnable { - Public voidrun () { the Try { + while(true) { ASYSTEM.OUT.PRINTLN ("\t\t\tconsumer reads" +Buffer.take ()); the //Put the thread into sleep +Thread.Sleep ((int) (Math.random () * 10000)); - } $}Catch(Interruptedexception ex) { $ ex.printstacktrace (); - } - } the } -}
Producer consumers of thread synchronization