Producer, consumer model member
Producer: Produce products and put them in the queue.
Consumer: Consumer products.
Queue: Data buffer area.
advantage
1. Unlock lotus root
Producers only pay attention to production, consumers only pay attention to consumption
2. Asynchronous
Synchronous: a calls b, a must wait for b to be connected before a can talk
to b Asynchronous: a sends a WeChat to b, a does not have to wait for a reply, b does not have to reply, b can reply when he is free
3. Balance speed difference
The production speed of the producer must be equal to the consumption speed of the consumer,
otherwise,
production>consumption will cause the queue to overflow, and
production<consumption will cause the queue to be empty.
Notification mechanism
wait(): let the current thread wait for
notify(): wake up a thread
notifyAll(): wake up all threads
Logic : The thread in Q3 is awakened, enters Q1, grabs the lock, and the thread that grabs the lock will perform the operation in Q2. Before performing the operation, check whether the queue is full, full, wait, and perform the operation when it is not full. After it is over, release lock.
Because Q2 can only have one thread, the object monitor lock mechanism is used in Q1
Code:
public class Producer implements Runnable{
private Queue<Product> queue;
private int maxCapacity;
public Producer(Queue queue, int maxCapacity) {
this.queue = queue;
this.maxCapacity = maxCapacity;
}
@Override
public void run() {
synchronized (queue) {
while (queue.size() == maxCapacity) {
//一定要用 while,而不是 if,下文解释
try {
System.out.println("生产者" + Thread.currentThread().getName() + "等待中... Queue 已达到最大容量,无法生产");
wait();
System.out.println("生产者" + Thread.currentThread().getName() + "退出等待");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (queue.size() == 0) {
//队列里的产品从无到有,需要通知在等待的消费者
queue.notifyAll();
}
Random random = new Random();
Integer i = random.nextInt();
queue.offer(new Product("产品" + i.toString()));
System.out.println("生产者" + Thread.currentThread().getName() + "生产了产品:" + i.toString());
}
}
}
logic:
1. The producer gets the lock, starts to work, checks whether the production box is full or not, and waits
2. The producer gets the lock, starts to work, checks whether the production box is full, not full, whether there is any product in the production box, if not, notify the consumer, and then
Start production
public class Consumer implements Runnable{
private Queue<Product> queue;
private int maxCapacity;
public Consumer(Queue queue, int maxCapacity) {
this.queue = queue;
this.maxCapacity = maxCapacity;
}
@Override
public void run() {
synchronized (queue) {
while (queue.isEmpty()) {
try {
System.out.println("消费者" + Thread.currentThread().getName() + "等待中... Queue 已缺货,无法消费");
wait();
System.out.println("消费者" + Thread.currentThread().getName() + "退出等待");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (queue.size() == maxCapacity) {
queue.notifyAll();
}
Product product = queue.poll();
System.out.println("消费者" + Thread.currentThread().getName() + "消费了:" + product.getName());
}
}
}
logic:
1. The consumer gets the lock, starts to consume the product, checks whether the production box is empty, is empty, wait
2. Consumers get the lock and start to consume the products, check whether the production box is empty, not empty, whether the production box is full of products, full, pass
Know that the producer produces the product and starts to consume the product