Tag: Sync log uses containe col obj to start notify
In the field of computer, producer-consumer problem (also called bounded-buffer problem) is a kind of classic multi-process synchronization problem. This issue describes two types of processes, the producer process and the consumer process, which share a fixed-size buffer as a queue. The task of a producer is to generate data and put it into a buffer, while consumers consume data (or remove it from the buffer). The number of each production or consumption data is one. When resolving the problem, make sure that when the buffer is full, no more data is added to it, and the consumer cannot extract the data from it when the buffer is empty.
When the buffer is full, the producer either goes into hibernation or discards the resulting data. Wait until the next time the consumer removes a piece of data from the buffer, notify the producer to continue adding data to the buffer. Similarly, when the consumer finds that the buffer is empty, the consumer goes into hibernation. When the producer writes data to the buffer, the producer wakes up the consumer to consume the data. This problem can be addressed through interprocess communication, typically using semaphores. If the problem is not addressed properly, it can lead to deadlocks, that is, producers and consumers are waiting for wake-up status.
Here is a reference to the online wording, wrote a very simple version. There are 4 files:
1. Container, Container.java
2. Producer, Producer.java
3. Consumer, Consumer.java
4. test file, Test.java
Producer.java
PackageCom.tuhooo.practice.pcmodel;/*** Producer*/ Public classProducerImplementsRunnable {PrivateContainer<integer>container; PrivateObject Producermonitor; PrivateObject Consumermonitor; Producer (Container<Integer>container, Object Producermonitor, Object Consumermonitor) { This. Container =container; This. producermonitor = Producermonitor;/*Producer's Lock*/ This. consumermonitor = Consumermonitor;/*Consumer's Lock*/ } Public voidrun () { while(true) {produce (); } } Private voidProduce () {if(Container.isfull ()) {synchronized(producermonitor) {Try { if(Container.isfull ()) {producermonitor.wait (); } } Catch(interruptedexception e) {e.printstacktrace (); } } } Else { synchronized(producermonitor) {if(!Container.isfull ()) {Container.add (0); Try{Thread.CurrentThread (). Sleep (1000); } Catch(interruptedexception e) {e.printstacktrace (); } System.out.println ("Producer" "+ Thread.CurrentThread (). GetId () +" "produced one, altogether" + container.getsize () + "each"); } } } if(!Container.isempty ()) { synchronized(consumermonitor) {if(!Container.isempty ()) {consumermonitor.notify (); } } } }}
Consumer.java
PackageCom.tuhooo.practice.pcmodel;/*** Consumer*/ Public classConsumerImplementsRunnable {PrivateContainer<integer>container; PrivateObject Producermonitor; PrivateObject Consumermonitor; Consumer (Container<Integer>container, Object Producermonitor, Object Consumermonitor) { This. Container =container; This. producermonitor = Producermonitor;/*Producer's Lock*/ This. consumermonitor = Consumermonitor;/*Consumer's Lock*/ } Public voidrun () { while(true) {consume (); } } /*How to write the consumption method*/ Private voidconsume () {if(Container.isempty ()) {//Consumer Hang up synchronized(consumermonitor) {Try { if(Container.isempty ()) {consumermonitor.wait (); } } Catch(interruptedexception e) {e.printstacktrace (); } } } Else { synchronized(consumermonitor) {if(!Container.isempty ()) {Container.get (); Try{Thread.CurrentThread (). Sleep (500); } Catch(interruptedexception e) {e.printstacktrace (); } System.out.println ("Consumer" + thread.currentthread (). GetId () + "" consumes one, plus "+ container.getsize () +" + "); } } } if(!Container.isfull ()) { synchronized(producermonitor) {if(!Container.isfull ()) {producermonitor.notify (); } } } }}
Container.java
PackageCom.tuhooo.practice.pcmodel;Importjava.util.LinkedList;Importjava.util.List;/*** Container*/ Public classContainer<t> { Private intcapacity; PrivateList<t>list; PublicContainer (intcapacity) { This. Capacity =capacity; List=NewLinkedlist<t>(); } /*adding to the container*/ Public synchronized BooleanAdd (T product) {if(List.size () <capacity) {List.add (product); return true; } return false; } /*take from the container*/ Public synchronizedT Get () {if(List.size () > 0) {List.remove (0); } return NULL; } /*Judging if it's full.*/ Public BooleanIsfull () {returnList.size () >=capacity; } Public BooleanIsEmpty () {returnList.size () = = 0; } Public synchronized intGetSize () {returnlist.size (); } Public intgetcapacity () {return This. Capacity; }}
Container a bit of pit is not know when should add synchronized
Test.java
PackageCom.tuhooo.practice.pcmodel; Public classTest { Public Static voidMain (string[] args) {Container<Integer> container =NewContainer<integer> (10); Object Producermonitor=NewObject (); Object Consumermonitor=NewObject (); Thread P1=NewThread (NewProducer (container, Producermonitor, consumermonitor)); Thread P2=NewThread (NewProducer (container, Producermonitor, consumermonitor)); Thread C1=NewThread (NewConsumer (container, Producermonitor, consumermonitor)); Thread C2=NewThread (NewConsumer (container, Producermonitor, consumermonitor)); P1.start (); P2.start (); C1.start (); C2.start (); }}
At present, the first to write, the temporary operation is not a problem, if there is a problem, please crossing pointed out.
Areas to be improved:
1. Container there is no better way to implement
2. Container can have multiple, so that you can randomly find a usable container assigned to producer or consumer
3. Feel a lot of synchronized in the code, feel the performance is not very good
Producer and consumer problem learning and Java implementations