1、什么是生产者和消费者模式?
生产者和消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通信,而是通过阻塞队列来进行通信,所以生产者生产完数据之后不等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力
2、生产者和消费者模式的作用是什么?
-
通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率
-
解耦,解耦意味着生产者和消费者之间的联系少,联系越少越可以独自发展而不需要受到相互的制约
3、生产者和消费者模式的实现
1)、使用synchronized与wait()和notify()/notifyAll()实现
// 生产者
public class Producer implements Runnable {
private Medium medium;
public Producer(Medium medium) {
super();
this.medium = medium;
}
@Override
public void run() {
while (true) {
medium.put();
}
}
}
// 消费者
public class Consumer implements Runnable {
private Medium medium;
public Consumer(Medium medium) {
super();
this.medium = medium;
}
@Override
public void run() {
while (true) {
medium.take();
}
}
}
// 中间商
public class Medium {
private int num = 0;
private static final int TOTAL = 20;
// 接收生产者数据
public synchronized void put() {
// 判断当前库存是否已经是最大库存容量
if (num < TOTAL) {
// 如果不是,生产完成之后,通知消费者进行消费
System.out.println("新增库存--->当前库存:" + ++num);
notifyAll();
} else {
// 如果是,通知生产者进行等待
try {
System.out.println("新增库存--->库存已满:" + num);
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 获取消费数据
public synchronized void take() {
// 判断当前库存是否不足
if (num > 0) {
// 如果充足,在消费者完成之后通知生产者进行生产
System.out.println("消费库存--->当前库存容量:" + --num);
notifyAll();
} else {
// 如果不足,通知消费者暂停消费
try {
System.out.println("消费库存--->库存不足:" + num);
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
Medium medium = new Medium();
new Thread(new Producer(medium)).start();
new Thread(new Producer(medium)).start();
new Thread(new Producer(medium)).start();
new Thread(new Consumer(medium)).start();
new Thread(new Consumer(medium)).start();
new Thread(new Consumer(medium)).start();
new Thread(new Consumer(medium)).start();
new Thread(new Consumer(medium)).start();
}
}
2)、使用lock与Condition实现
public class Middleman {
private static final int TOTAL = 20;
private int num;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void put() {
try {
lock.lock();
if (num < TOTAL) {
System.out.println("新增库存--->当前库存:" + ++num);
condition.signalAll();
} else {
System.out.println("新增库存--->库存已满:" + num);
condition.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void take() {
try {
lock.lock();
if (num > 0) {
System.out.println("消费库存--->当前库存容量:" + --num);
condition.signalAll();
} else {
System.out.println("消费库存--->库存不足:" + num);
condition.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}