Producer and consumer issues in java threads, java producer

Source: Internet
Author: User

Producer and consumer issues in java threads, java producer

I. Concepts

The producer-consumer issue is a golden multi-thread collaboration problem. The producer is responsible for producing and storing the product in the warehouse. The consumer obtains and consumes the product from the warehouse. When the Warehouse is full, the producer must stop production until the warehouse stores products. When the Warehouse is empty, the consumer must stop consumption until there are products in the warehouse.

The following technologies are mainly used to solve the producer/consumer problem: 1. Simulate the producer with a thread and store the product in the store continuously in the run method. 2. Use threads to simulate consumers and continuously obtain products from the repository in the run method. 3

. When the number of products is 0, the current consumer thread enters the waiting state by calling the wait method. When a new product is saved, the consumer y method is called to wake up the waiting consumer thread. When the Warehouse is full, the wait method is called to make the current producer thread wait. When a consumer obtains the product, the notify method is called to wake up the waiting producer thread.

Ii. Instances

  

Package book. thread. product;

Public class Consumer extends Thread {
Private Warehouse warehouse; // The consumer obtains the product Warehouse.
Private boolean running = false; // specifies whether to end the flag of the thread.
Public Consumer (Warehouse warehouse, String name ){
Super (name );
This. warehouse = warehouse;
}
Public void start (){
This. running = true;
Super. start ();
}
Public void run (){
Product product;
Try {
While (running ){
// Obtain the product from the Repository
Product = warehouse. getProduct ();
Sleep (500 );
}
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
// Stop the consumer thread
Public void stopConsumer (){
Synchronized (warehouse ){
This. running = false;
Warehouse. policyall (); // notify the thread waiting for the warehouse
}
}
// Whether the consumer thread is running
Public boolean isRunning (){
Return running;
}
}

 

Package book. thread. product;

Public class Producer extends Thread {
Private Warehouse warehouse; // producer storage product Warehouse
Private static int produceName = 0; // Product Name
Private boolean running = false; // specifies whether to end the flag of the thread.

Public Producer (Warehouse warehouse, String name ){
Super (name );
This. warehouse = warehouse;
}
Public void start (){
This. running = true;
Super. start ();
}
Public void run (){
Product product;
// Produce and store the product
Try {
While (running ){
Product = new Product (+ + produceName) + "");
This. warehouse. storageProduct (product );
Sleep (300 );
}
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
// Stop the producer thread
Public void stopProducer (){
Synchronized (warehouse ){
This. running = false;
// Notify the thread waiting for the warehouse
Warehouse. policyall ();
}
}
// Whether the producer thread is running
Public boolean isRunning (){
Return running;
}
}

 

Package book. thread. product;

Public class Product {
Private String name; // Product name
Public Product (String name ){
This. name = name;
}
Public String toString (){
Return "Product-" + name;
}
}

 

Package book. thread. product;

// The product warehouse class, which uses an array internally to represent the cyclic queue to store the product
Public class Warehouse {
Private static int CAPACITY = 11; // repository CAPACITY
Private Product [] products; // products in the repository
// Products in the [front, rear] range are not consumed
Private int front = 0; // subscript of the first unconsumed product in the current Warehouse
Private int rear = 0; // Add 1 to the subscript of the last unconsumed product in the repository
Public Warehouse (){
This. products = new Product [CAPACITY];
}
Public Warehouse (int capacity ){
This ();
If (capacity> 0 ){
CAPACITY = capacity + 1;
This. products = new Product [CAPACITY];
}
}

// Obtain a product from the Repository
Public Product getProduct () throws InterruptedException {
Synchronized (this ){
Boolean consumerRunning = true; // indicates whether the consumer thread is still running.
Thread currentThread = Thread. currentThread (); // get the current Thread
If (currentThread instanceof Consumer ){
ConsumerRunning = (Consumer) currentThread). isRunning ();
} Else {
Return null; // a non-consumer cannot obtain the product.
}
// If the consumer thread is running but there is no product in the warehouse, the consumer thread continues to wait
While (front = rear) & consumerRunning ){
Wait ();
ConsumerRunning = (Consumer) currentThread). isRunning ();
}
// If the consumer thread has stopped running, exit this method and cancel obtaining the product.
If (! ConsumerRunning ){
Return null;
}
// Obtain the first product that is not currently consumed
Product product = products [front];
System. out. println ("Consumer [" + currentThread. getName () + "] getProduct:" + product );
// Move the subscript of the currently unconsumed product to the first place.
Front = (front + 1 + CAPACITY) % CAPACITY;
System. out. println ("number of products not consumed in the repository:" + (rear + CAPACITY-front) % CAPACITY );
// Notify other waiting threads
Notify ();
Return product;
}
}
// Store a product to the warehouse
Public void storageProduct (Product product) throws InterruptedException {
Synchronized (this ){
Boolean producerRunning = true; // indicates whether the producer thread is running.
Thread currentThread = Thread. currentThread ();
If (currentThread instanceof Producer ){
ProducerRunning = (Producer) currentThread). isRunning ();
} Else {
Return;
}
// If the last unconsumed product matches the subscript of the first unconsumed product, there is no storage space.
// If there is no storage space and the producer thread is still running, the producer thread waits for the repository to release the product.
While (rear + 1) % CAPACITY = front) & producerRunning ){
Wait ();
ProducerRunning = (Producer) currentThread). isRunning ();
}
// If the production thread has stopped running, the product storage will be stopped.
If (! ProducerRunning ){
Return;
}
// Save the product to the repository
Products [rear] = product;
System. out. println ("Producer [" + Thread. currentThread (). getName () + "] storageProduct:" + product );
// Move the rear subscript loop to the next position
Rear = (rear + 1) % CAPACITY;
System. out. println ("number of products not consumed in the repository:" + (rear + CAPACITY-front) % CAPACITY );
Notify ();
}
}
}

 

Package book. thread. product;

Public class TestProduct {
Public static void main (String [] args ){
Warehouse warehouse = new Warehouse (10); // create a Warehouse with a capacity of 10
// Create producer threads and consumers
Producer producers1 = new Producer (warehouse, "producer-1 ");
Producer producers2 = new Producer (warehouse, "producer-2 ");
Producer producers3 = new Producer (warehouse, "producer-3 ");
Consumer consumer1 = new Consumer (warehouse, "consumer-1 ");
Consumer consumer2 = new Consumer (warehouse, "consumer-2 ");
Consumer consumer3 = new Consumer (warehouse, "consumer-3 ");
Consumer consumer4 = new Consumer (warehouse, "consumer-4 ");
// Start the producer thread and consumer thread
Producers1.start ();
Producers2.start ();
Consumer1.start ();
Producers3.start ();
Consumer2.start ();
Consumer3.start ();
Consumer4.start ();
// Let the producer/consumer program run for 1600 ms
Try {
Thread. sleep (1600 );
} Catch (InterruptedException e ){
E. printStackTrace ();
}
// Stop the consumer thread
Producers1.stopProducer ();
Consumer1.stopConsumer ();
Producers2.stopProducer ();
Consumer2.stopConsumer ();
Producers3.stopProducer ();
Consumer3.stopConsumer ();
Consumer4.stopConsumer ();
}
}

Output result:

Producer [producer-1] storageProduct: Product-1
Number of products not consumed in the warehouse: 1
Consumer [consumer-2] getProduct: Product-1
Number of products not consumed in the warehouse: 0
Producer [producer-3] storageProduct: Product-3
Number of products not consumed in the warehouse: 1
Producer [producer-2] storageProduct: Product-2
Number of products not consumed in the warehouse: 2
Consumer [consumer-3] getProduct: Product-3
Number of products not consumed in the warehouse: 1
Consumer [consumer-1] getProduct: Product-2
Number of products not consumed in the warehouse: 0
Producer [producer-1] storageProduct: Product-4
Number of products not consumed in the warehouse: 1
Consumer [consumer-4] getProduct: Product-4
Number of products not consumed in the warehouse: 0
Producer [producer-3] storageProduct: Product-6
Number of products not consumed in the warehouse: 1
Producer [producer-2] storageProduct: Product-5
Number of products not consumed in the warehouse: 2
Consumer [consumer-1] getProduct: Product-6
Number of products not consumed in the warehouse: 1
Consumer [consumer-2] getProduct: Product-5
Number of products not consumed in the warehouse: 0
Producer [producer-1] storageProduct: Product-7
Number of products not consumed in the warehouse: 1
Consumer [consumer-3] getProduct: Product-7
Number of products not consumed in the warehouse: 0
Producer [producer-3] storageProduct: Product-8
Number of products not consumed in the warehouse: 1
Producer [producer-2] storageProduct: Product-9
Number of products not consumed in the warehouse: 2
Consumer [consumer-4] getProduct: Product-8
Number of products not consumed in the warehouse: 1
Producer [producer-1] storageProduct: Product-10
Number of products not consumed in the warehouse: 2
Producer [producer-3] storageProduct: Product-11
Number of products not consumed in the warehouse: 3
Producer [producer-2] storageProduct: Product-12
Number of products not consumed in the warehouse: 4
Consumer [consumer-1] getProduct: Product-9
Number of products not consumed in the warehouse: 3
Consumer [consumer-2] getProduct: Product-10
Number of products not consumed in the warehouse: 2
Consumer [consumer-3] getProduct: Product-11
Number of products not consumed in the warehouse: 1
Producer [producer-3] storageProduct: Product-13
Number of products not consumed in the warehouse: 2
Producer [producer-1] storageProduct: Product-14
Number of products not consumed in the warehouse: 3
Producer [producer-2] storageProduct: Product-15
Number of products not consumed in the warehouse: 4
Consumer [consumer-4] getProduct: Product-12
Number of products not consumed in the warehouse: 3
Consumer [consumer-1] getProduct: Product-13
Number of products not consumed in the warehouse: 2
Consumer [consumer-2] getProduct: Product-14
Number of products not consumed in the warehouse: 1
Producer [producer-1] storageProduct: Product-16
Number of products not consumed in the warehouse: 2
Producer [producer-3] storageProduct: Product-17
Number of products not consumed in the warehouse: 3
Producer [producer-2] storageProduct: Product-18
Number of products not consumed in the warehouse: 4

Analysis: A product warehouse is created in the main method, without which three producer threads and four consumer threads are associated to start these threads to make the producer/consumer model operate, when the program runs for MS, all producers stop producing products and consumers stop consuming products.

The producer thread Product produces a Product within ms in the run method and stores it in the warehouse. The Consumer thread Consumer obtains a Product from the warehouse without ms in the run method.

Warehouse is responsible for storing and distributing products. The storageProduct method is used to store products. When the Warehouse is full, the current thread enters the waiting state. That is, if producer thread A finds that the warehouse is full and cannot be stored when the storageProduct method is called, the system enters the waiting state. When the storage product is successful, call the consumer y method to wake up the waiting consumer thread.

The getProduct method is used to advance the product. When the Warehouse is empty, the current thread enters the waiting state. That is, if consumer thread B finds that the warehouse is empty when calling the getProduct method to obtain the product, the system enters the waiting state. When the product is extracted successfully, call the y method to wake up the waiting producer thread.

Related Article

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.