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(); } }