Multithread Instances - Producer Consumer Instances

problem

Productors hand products to clerks, and consumers take products from clerks.
Shop assistants can only hold a fixed number of products at a time (e.g. 20).
If the producer tries to produce more products, the shop assistant will ask the producer to stop. If there is space in the shop, the producer will be informed to continue production.
If there is no product in the store, the clerk will tell the consumer to wait, and if there is a product in the store, the customer will be informed to take the product.

Two problems may arise here:

1. When the producer is faster than the consumer, the consumer will miss some data that has not been retrieved.
2. When consumers are faster than producers, consumers will get the same data.

Analytical issues:

1. Using multithreading: producers and consumers
2. Shared data: the current number of products
3. Thread communication problems: there is communication between producers and consumers

Implementation code:

// Clerk
class Clerk {
    // product
    int product;

    // Method of Producing Products
    public synchronized void addProduct() {
	if (product >= 20) {
	    try {
		wait();
	    } catch (InterruptedException e) {
		e.printStackTrace();
	    }
	} else {
	    product++;
	    System.out.println(Thread.currentThread().getName() + "Production No." + product + "A product");
	    notifyAll();
	}
    }
 // The Method of Consuming Products
    public synchronized void consumeProduct() {
	if (product <= 0) {
	    try {
		wait();
	    } catch (InterruptedException e) {
		e.printStackTrace();
	    }
	}else {
	    product--;
	    System.out.println(Thread.currentThread().getName() + "Consume the first" + product + "A product");
	    notifyAll();
	}
    }
}
// Producer
class Producer implements Runnable{
    Clerk clerk;
    
     public Producer(Clerk clerk) {
	 this.clerk=clerk;
    }
     
    @Override
    public void run() {
	// yield a product
	System.out.println("Producers begin to produce products....");
	while (true) {
	    try {
		Thread.currentThread().sleep(100);
	    } catch (InterruptedException e) {
		e.printStackTrace();
	    }
	    // Method of invoking production products
	    clerk.addProduct();
	}
    }
    
}
// Consumer
class Consumer implements Runnable{
    
    Clerk clerk;
    
    public Consumer(Clerk clerk){
	this.clerk=clerk;
    }
    
    @Override
    public void run() {
	 // Consumer products
	System.out.println("Start consuming products...");
	while (true) {
	    try {
		Thread.currentThread().sleep(100);
	    } catch (InterruptedException e) { 
		e.printStackTrace();
	    }
	    // Method of invoking consumer products
	    clerk.consumeProduct();
	}
	
    }

}
public class TestProduce {
    public static void main(String[] args) {
	Clerk clerk = new Clerk();
	// Creating Producer and Consumer Objects
	Producer p1 = new Producer(clerk);
	Consumer c1 = new Consumer(clerk);
	// Create a producer thread
	Thread t1 = new Thread(p1);
	Thread t3 = new Thread(p1);
	// Creating consumer threads
	Thread t2 = new Thread(c1);
	
	t1.setName("Producer 1");
	t2.setName("Consumer 2");
	t3.setName("Producer 2");
	
	t1.start();
	t2.start();
	t3.start();
    }
}

Posted by benracer on Tue, 01 Oct 2019 16:22:11 -0700