生产者消费者模型
什么是生产者消费者模型
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之
间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,
直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一
个缓冲区,平衡了生产者和消费者的处理能力。
这个阻塞队列就是用来给生产者和消费者解耦的。纵观大多数设计模式,都会找一个第三者出来进行
解耦,如工厂模式的第三者是工厂类,模板模式的第三者是模板类。在学习一些设计模式的过程中,
如果先找到这个模式的第三者,能帮助我们快速熟悉一个设计模式。
模型代码
package com.donews.frame.sdk;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by 79653 on 2018/10/22.
* 描述:
*/
public class JavaActivity {
public static void main(String[] args) {
//数据缓冲区,用来解耦
List<RunnableData> mQuene=new ArrayList<>();
Producter producter=new Producter(mQuene);
Producter producter1=new Producter(mQuene);
Producter producter2=new Producter(mQuene);
Producter producter3=new Producter(mQuene);
Producter producter4=new Producter(mQuene);
Consumer consumer=new Consumer(mQuene);
Consumer consumer1=new Consumer(mQuene);
Consumer consumer2=new Consumer(mQuene);
Consumer consumer3=new Consumer(mQuene);
Consumer consumer4=new Consumer(mQuene);
ExecutorService service=Executors.newCachedThreadPool();
service.execute(producter);
service.execute(producter1);
service.execute(producter2);
service.execute(producter3);
service.execute(producter4);
service.execute(consumer);
service.execute(consumer1);
service.execute(consumer2);
service.execute(consumer3);
service.execute(consumer4);
}
static class RunnableData {
public int data;
public RunnableData(int data) {
this.data = data;
}
}
static class Producter implements Runnable {
List<RunnableData> mDataList;
Random mRandom = new Random();
public Producter(List<RunnableData> data) {
mDataList = data;
}
@Override
public void run() {
try {
while (true) {
if (Thread.currentThread().isInterrupted()) {
return;
}
synchronized (mDataList) {
if (mDataList != null && mDataList.size() > 10) {
//唤醒其他线程,同时自己进入等待状态
mDataList.notifyAll();
mDataList.wait();
} else {
RunnableData data = new RunnableData(mRandom.nextInt());
mDataList.add(data);
System.out.println("生产者生产了一个数据---------" + data.data);
}
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
// Thread.currentThread().isInterrupted();
}
}
}
static class Consumer implements Runnable {
List<RunnableData> mDataList;
public Consumer(List<RunnableData> data) {
mDataList = data;
}
@Override
public void run() {
try {
while (true) {
if (Thread.currentThread().isInterrupted()) {
return;
}
synchronized (mDataList) {
if (mDataList == null || mDataList.size() == 0) {
mDataList.notifyAll();
mDataList.wait();
}
RunnableData data = mDataList.remove(0);
System.out.println("消费者消费了一条数据---" + data.data);
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
实际应用实例
- 最近公司的项目设计到广告这一层面,我们想在广告使用时有一个池子会一直有广告,然后需要的 时候我们就会从这个池子里面去取,这和我们的模型一模一样,代码几乎也一样,只是生产者和消费者干的是行情不一样