The wait(), notify(), and notifyAll() methods are the three methods of Object.

Wait () causes the current thread to wait until:

  • Other thread callsnotify()Methods ornotifyAll()methods
  • Another thread interrupts the current thread
  • The specified wait time is up

The way it’s used is in a loop

synchronized (obj) {
    // The condition is not met
    while (condition does not hold) {
        obj.wait();
    }
    // Execute the code that meets the criteria
}
Copy the code

Calling wait() releases the lock on the current thread, leaving the CPU in the wait state. Notify () and notifyAll() both wake up the currently waiting thread. NotifyAll () wakes up all waiting threads. NotifyAll () wakes up all waiting threads. The thread will not execute the task immediately after being woken up. It is determined by the system which thread will execute the task. Wait (), notify(), and notifyAll() need to be included in the Syncronized code block or method.

Implement a consumer and producer pattern using wait(), notify(), and notifyAll().

Consumers and producers have a common container, from which consumers take data for consumption, and producers put data into the container after production. When the container is empty, consumers block, while producers produce data; When the container is full, the producer stops producing and notifies the consumer to consume.

The container

public class Container {
    private static final int MAX_SIZE = 5;
    private final LinkedList<Object> list = new LinkedList<>();

    / / production
    public void product(a) {
        synchronized (list) {
            while (list.size() >= MAX_SIZE) { // The producer enters the wait state when the number of data in the container reaches the maximum
                try {
                    System.out.println("The container is full. Yes." + list.size() + "A piece of data --" + Thread.currentThread().getName());
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            list.addFirst(new Object());

            System.out.println("+++++ producer produces a piece of data that has" + list.size() + "A piece of data --"+ Thread.currentThread().getName()); list.notifyAll(); }}public void consume(a) {
        synchronized (list) {
            while (list.size() <= 0) { // If the container is empty, the consumer enters the wait state
                try {
                    System.out.println("The container has no data --" + Thread.currentThread().getName());
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            list.removeLast();
            System.out.println("----- consumer consumes a piece of data, there is" + list.size() + "A piece of data --"+ Thread.currentThread().getName()); list.notifyAll(); }}}Copy the code

producers

public class Producer implements Runnable{
    private final Container mContainer;

    public Producer(Container container) {
        mContainer = container;
    }


    @Override
    public void run(a) { mContainer.product(); }}Copy the code

consumers

public class Consumer implements Runnable {
    private final Container mContainer;

    public Consumer(Container container) {
        mContainer = container;
    }

    @Override
    public void run(a) { mContainer.consume(); }}Copy the code
public static void main(String[] args) {
    Container container = new Container();

    for (int i = 0; i < 8; i++) {
        Producer producer = new Producer(container);
        Thread thread = new Thread(producer);
        thread.setName("Producer thread" + i);
        thread.start();
    }

    for (int i = 0; i < 8; i++) {
        Consumer consumer = new Consumer(container);
        Thread thread = new Thread(consumer);
        thread.setName("Consumer thread"+ i); thread.start(); }}Copy the code

Synchronized in the Container class holds a List lock, so wait(), notify(), and notifyAll() must all call list. Synchrozied can also hold this, which indicates that the current Container lock is synchronized, or synchronized, which means that the wait(), notify(), and notifyAll() methods must call the Container methods. Either this.wait() or wait().

There will be a follow-up article devoted to synchronized.