Producer consumer mode and Guarded suspension mode It is similar, except that the guarded suspension mode does not limit the length of the buffer zone. The producerconsumer mode assumes that the produced product is placed in a buffer zone with a limited length (like a product table, it can be placed in a limited space), if the buffer is full, the producer must stop putting the product into the buffer until the consumer has taken the product and has space, if there is no product in the buffer zone, the consumer must wait until a new product is put in the buffer zone. A simple UML sequence diagram is shown below: In simple terms, the producer consumer mode is like adding a dual protection and a waiting guarded susion sion mode, and its two protections are opposite to the waiting conditions, A simple process architecture implemented in Java is as follows:
Import java. util. Collections list; Public class producttable { Private listing list products = new listing list (); Public synchronized void addproduct (product) { while (products. size ()> = 2) {// Capacity Limit: 2 try { wait (); }< br> catch (interruptedexception E) {}< BR >} products. addlast (product); policyall (); }< br> Public synchronized product getproduct () { while (products. size () <= 0) { try { wait (); }< br> catch (interruptedexception E) {}< BR >} Product = (product) products. removefirst (); Policyall ();
Return product; } } The following is the simplest example: the producer generates an integer and places it on the table at a time, while the consumer consumes an integer. Only one integer can be placed on the table at a time. If an integer already exists on the table, the producer waits for the consumer to consume the integer and notifies the producer to produce the next integer. If there is no integer on the table, the consumer waits for the producer to produce the integer and notifies the consumer to consume the integer.
Public class producer extends thread { Private producttable;
Public producer (producttable ){ This. producttable = producttable; }
Public void run (){ System. Out. println ("produce integer ......"); For (INT Product = 1; product <= 10; product ++ ){ Try { // Wait for a random time Thread. Sleep (INT) math. Random () * 3000 ); } Catch (interruptedexception e ){ E. printstacktrace (); } Producttable. setintproduct (product ); } } }
Public class Consumer extends thread { Private producttable;
Public consumer (producttable ){ This. producttable = producttable; }
Public void run (){ For (INT I = 1; I <= 10; I ++ ){ Try { // Wait for a random time Thread. Sleep (INT) (math. Random () * 3000 )); } Catch (interruptedexception e ){ E. printstacktrace (); } Producttable. getproductint (); } } } The producer puts the product on the table, and the consumer removes the product from the table. Therefore, the table is a place for maintenance to determine whether the product is placed or consumed. It determines who must wait and notify:
Public class producttable { Private int productint =-1; //-1 for no product Public synchronized void setintproduct (INT product ){ If (productint! =-1 ){ Try { Wait (); } Catch (interruptedexception e ){ E. printstacktrace (); } } productint = product; system. out. println ("set (" + product + ")"); Policy (); }< br> Public synchronized int getproductint () { If (productint =-1) { try { wait (); }< br> catch (interruptedexception E) { E. printstacktrace (); }< BR >} Int P = productint; System. Out. println ("Get (" + productint + ")"); Productint =-1;
Notify ();
Return P; } } The producer produces 10 integers, while the consumer consumes 10 integers. Because only one integer can be placed on the table, one is consumed for each production. |