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 executesrun
Method, 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