There are so many BB S above. It should be understood by taking a producer consumer chestnut as an example:
package com.thr; /** * @author Administrator * @date 2020-04-02 * @desc synchronized+wait+notify Thread communication example (producer consumer model) */ public class ProducerConsumerWaitNotify { public static void main(String[] args) { Resource resource = new Resource(); //Create 3 producer threads Thread t1 = new Thread(new Producer(resource),"Production thread 1"); Thread t2 = new Thread(new Producer(resource),"Production thread 2"); Thread t3 = new Thread(new Producer(resource),"Production thread 3"); //Create 2 consumer threads Thread t4 = new Thread(new Consumer(resource),"Consumption thread 1"); Thread t5 = new Thread(new Consumer(resource),"Consumption thread 2"); //Producer thread start t1.start(); t2.start(); t3.start(); //Consumer thread start t4.start(); t5.start(); } } /** * Shared resources (warehouse) */ class Resource{ //Current resource quantity private int num = 0; //Maximum number of resources private int size = 10; //Production resources public synchronized void add(){ if (num < size){ num++; System.out.println("producer--" + Thread.currentThread().getName() + "--Produce a resource. The current resource pool has" + num + "individual"); notifyAll(); }else{ try { wait(); System.out.println("producer--"+Thread.currentThread().getName()+"Enter the waiting state and wait for notification"); } catch (InterruptedException e) { e.printStackTrace(); } } } //Consumption resources public synchronized void remove(){ if (num > 0){ num--; System.out.println("consumer--" + Thread.currentThread().getName() + "--Consume a resource," + "The current thread pool has" + num + "individual"); notifyAll(); }else{ try { wait(); System.out.println("consumer--" + Thread.currentThread().getName() + "Enter the waiting state and wait for notification"); } catch (InterruptedException e) { e.printStackTrace(); } } } } /** * Producer thread */ class Producer implements Runnable{ //Shared resource object private Resource resource; public Producer(Resource resource) { this.resource = resource; } @Override public void run() { while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } resource.add(); } } } /** * Consumer thread */ class Consumer implements Runnable{ //Shared resource object private Resource resource; public Consumer(Resource resource) { this.resource = resource; } @Override public void run() { while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } resource.remove(); } } }
The results of the operation are as follows:
In fact, a "warehouse" should be added to the producer consumer model, because the model is not convincing without the "warehouse" producer consumer model. For this model, we should clarify the following points:
- The producer only produces when the warehouse is not full, and stops production when the warehouse is full.
- Consumers can only consume when there are products in the warehouse, and wait when the warehouse is empty.
- When consumers find that there is no product to consume in the warehouse, they will notify the producer for production.
- When producing consumable products, producers should inform waiting consumers to consume.
Let's compare the similarities and differences between sleep() and wait()?
Same point: both can make the current thread enter the blocking state.
difference:
- ① . the declared positions are different: sleep() is declared in Thread class and wait() is declared in object class.
- ② The requirements for calling are different: sleep() can be called in any required scenario. wait() must be used in a synchronization code block or synchronization method.
- ③ Release the synchronization monitor: if both methods are used in the synchronization code block or synchronization method, sleep() will not release the lock, and wait() will release the lock.
- ④ How to wake up: sleep() wakes up automatically, and wait() needs to call notify() and notifyAll() manually.