First define the resource class: contains the resource quantity, consumption method, production method

When resource is 0, producer produces resource

When the resource is 1, the consumer consumes the resource

Public class Resource {// The number of current resources int num=0; Int size=1; Public synchronized void remove(){if(num==0){try {system.out.println (" synchronized "); wait(); } catch (InterruptedException e) { e.printStackTrace(); } } num--; System.out.println(" consumer Thread: "+ thread.currentThread ().getName()+ num); notifyAll(); } public synchronized void put(){if(num==size){try {system.out.println (" synchronized "); wait(); } catch (InterruptedException e) { e.printStackTrace(); } } num++; System.out.println(" producer Thread: "+ thread.currentThread ().getName()+ num); notifyAll(); }}Copy the code

Creating a consumer thread

Public class Consumer implements Runnable {private Resource implements Runnable; public Consumer(Resource resource) { this.resource = resource; } @Override public void run() { for(int i=0; i<10; i++){ resource.remove(); }}}Copy the code

Creating a producer thread

Public class Producer implements Runnable {private Resource implements Runnable; public Producer(Resource resource) { this.resource = resource; } @Override public void run() { for(int i=0; i<10; i++){ resource.put(); }}}Copy the code

The thread of execution

public static void main(String[] args) {
    Resource resource = new Resource();
    Consumer consumer = new Consumer(resource);
    Producer producer = new Producer(resource);
    new Thread(consumer).start();
    new Thread(producer).start();
}
Copy the code

It can be found that the thread is executing normally

But when we have two consumers and two producers, thread execution becomes abnormal

public static void main(String[] args) { Resource resource = new Resource(); Consumer consumer = new Consumer(resource); Producer producer = new Producer(resource); New Thread(producer," producer 1").start(); New Thread(producer," producer 2").start(); New Thread(consumer," consumer 1").start(); New Thread(consumer," consumer 2").start(); }Copy the code

This is the false wake up problem

When our thread executesstart, the threads enter the ready state

Producer 1 acquires CPU execution, becomes running, and executesrunMethod, number of resources +1

Producer 1 and producer 2 then acquire CPU execution because the number of resources is 1 and the thread is blocked

The consumer gets CPU execution, number of resources -1, and wakes up the blocked thread

And that’s where it started

When the producer executes again, picking up where it blocked, it is no longer necessary to determine whether the number of resources is zero

False wake up occurs because there is no judgment from blocked state to ready state to running state

We can make a judgment every time we get the right to do something, just change the if judgment to the while judgment

The execution is normal