生产消费模式
在实际的软件开发过程中,经常会碰到如下场景: 某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象的成为生产者;而处理数据的模块,就成为消费者。
单单抽象出生产者和消费者,还不够算上是生产者/消费者模式。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介(类似于商店,生产者生产完供货给商店,商店卖给消费者),生产者把数据放入缓冲区,而消费者从缓冲区取出数据。
生产者消费者的关系如下图所示:
生产者消费者模式的原理描述:
1. 生产者仅仅在仓储未满时候生产,仓满则停止生产。
2. 消费者仅仅在仓储有产品时候才能消费,仓空则等待生产。
3. 当消费者发现仓储没产品可消费时,会通知生产者生产。
4. 生产者在生产出可消费产品时,应该通知等待的消费者去消费。
程序实例:
1. 先创建一个库存商品管理类
public class ProductStorage {
public static final int Maximum = 100;
public static int Currentimun = 50;
private static ProductStorage instance;
private ProductStorage() {
}
public static ProductStorage getInstance() {
if (instance == null) {
instance = new ProductStorage();
}
return instance;
}
public synchronized void product() {
while (Currentimun >= (Maximum / 2)) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Currentimun++;
System.out.println("当前线程:" + Thread.currentThread().getName() + "生产了一个商品,当前库存量:" + Currentimun);
notifyAll();
}
public synchronized void consume() {
while (Currentimun <= 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Currentimun--;
System.out.println("当前线程:" + Thread.currentThread().getName() + "消费了一个商品,当前库存:" + Currentimun);
notifyAll();
}
}
- 创建商品生产者模型
public class Producter implements Runnable{
@Override
public void run() {
while(true){
try{
Thread.sleep(500);
}catch(InterruptedException e){
e.printStackTrace();
}
ProductStorage.getInstance().product();
}
}
}
- 创建商品消费者模型
public class Consumer implements Runnable {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ProductStorage.getInstance().consume();
}
}
}
- 最后创建主程序 ,主程序的作用,其实就是启动线程。
public class TestProduct {
public static void main(String[] args) {
Producter p=new Producter();
Consumer c =new Consumer();
new Thread(p).start();
new Thread(c).start();
}
}
生产者消费者模式的优点:
1. 将生产模块和消费模块分隔开,从而降低了程序的耦合,便于程序的扩展和维护。
2. 将生产模块和消费模块的分隔,可使生产模块的运行不再依赖消费模块的执行,由同步改为异步执行并且都可支持并发,从而大大提高了程序的效率。
3. 生产者产生的数据存放在缓冲区中,消费者可以按照自己的逻辑来取出数据处理,从而有效的避免消费模块任务执行负载不均的问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)