wait/notify to implement producer consumer model

Why use producer and consumer models?

In the world of threads, producers produce some data, and consumers consume and use these data, but their speed is likely to be inconsistent. Sometimes producers are fast, sometimes producers are slow and consumers are fast, so a design pattern is needed to solve this problem, rather than one is too fast and one is too slow, so producer consumption is born In fact, this design mode couples the producer and the consumer, so as to achieve a more smooth cooperation.

What problems can be solved?

It can solve the problem that production is too fast and consumption is insufficient or production is not enough and consumption is too fast, and it can decouple the producer and consumer.

Code demo

Data container: used to store the produced data, defines the put method of production data and the take method of consumption data.

  • put method implementation logic: first, both methods need to be locked synchronously to prevent thread safety problems, and wait also needs monitor lock, which needs to be defined in synchronized decorated methods. The logic inside is also very simple. If the storage queue is full, we will call wait() to wait and no longer produce data.
  • The take method implements the logic: if the queue is empty, wait is called.
  • notify wake-up logic:
    • Producer's production is too fast: if producer's production is too fast, the storage will be full. At this time, production data will no longer be waiting. Consumers will consume data. After consumption, they will call notify method to wake up producer to continue production data.
    • Consumer consumption is too fast: if consumer consumption is too fast, the storage will be empty. At this time, the consumer checks that there is no data consumption and is waiting. After the producer produces a piece of data, the consumer will be awakened to continue consuming data.
class EventStorage {

    private int maxSize;
    private LinkedList<Date> storage;

    public EventStorage() {
        maxSize = 10;
        storage = new LinkedList<>();
    }

    public synchronized void put() {
        while (storage.size() == maxSize) {
            try {
               wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        storage.add(new Date());
        System.out.println("In the warehouse" + storage.size() + "A product.");
        notify();
    }

    public synchronized void take() {
        while (storage.size() == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Got it." + storage.poll() + ",Now the warehouse is left" + storage.size());
        notify();
    }
}

Producer: for production data, you can see that the storage in the producer is used to store the production data, and the run method is used to complete the task of production data.

class Producer implements Runnable {

    private EventStorage storage;

    public Producer(EventStorage storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            storage.put();
        }
    }
}

Consumer: for consumption data

class Consumer implements Runnable {

    private EventStorage storage;

    public Consumer(EventStorage storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            storage.take();
        }
    }
}

Main class: start one thread to produce data and another thread to consume data.

public class ProducerConsumerModel {

    public static void main(String[] args) {
        EventStorage eventStorage = new EventStorage();
        Producer producer = new Producer(eventStorage);
        Consumer consumer = new Consumer(eventStorage);
        new Thread(producer).start();
        new Thread(consumer).start();
    }
}

Print results:

There is a product in the warehouse.
There are two products in the warehouse.
There are three products in the warehouse.
There are four products in the warehouse.
There are five products in the warehouse.
There are six products in the warehouse.
Got Sat Nov 02 20:33:09 CST 2019, now there are 5 left in the warehouse
 Got Sat Nov 02 20:33:09 CST 2019, now there are 4 left in the warehouse
 Got Sat Nov 02 20:33:09 CST 2019, now there are 3 left in the warehouse
 Got Sat Nov 02 20:33:09 CST 2019, now there are 2 left in the warehouse
 Got Sat Nov 02 20:33:09 CST 2019, now the warehouse has 1
 Got Sat Nov 02 20:33:09 CST 2019, now there is 0 left in the warehouse
 There is a product in the warehouse.
There are two products in the warehouse.
There are three products in the warehouse.
There are four products in the warehouse.
There are five products in the warehouse.
There are six products in the warehouse.
There are seven products in the warehouse.
There are eight products in the warehouse.
There are nine products in the warehouse.
There are 10 products in the warehouse.
Got Sat Nov 02 20:33:09 CST 2019, now there are 9 left in the warehouse
 Got Sat Nov 02 20:33:09 CST 2019, now there are 8 left in the warehouse
 Got Sat Nov 02 20:33:09 CST 2019, now there are 7 left in the warehouse
...
95 original articles published, 300 praised, 20000 visitors+
Private letter follow

Added by kevintynfron on Tue, 03 Mar 2020 04:50:26 +0200