java线程生产者与消费者模型

多线程之间通信–生产者与消费者模型

生产者消费者模式并不是GOF提出的23种设计模式之一,23种设计模式都是建立在面向对象的基础之上的,但其实面向过程的编程中也有很多高效的编程模式,生产者消费者模式便是其中之一,它是我们编程过程中最常用的一种设计模式。
生产者消费者模式是为了解决哪一类问题而产生的呢?在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。单单抽象出生产者和消费者,还够不上是生产者/消费者模式。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据。

生产者消费者模式的原理描述:
(1)生产者仅仅在仓储未满时候生产,仓满则停止生产。
(2)消费者仅仅在仓储有产品时候才能消费,仓空则等待。
(3)当消费者发现仓储没产品可消费时候会通知生产者生产。
(4)生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

生产者消费者模式的优点:
(1)将生产模块和消费模块分隔开,从而降低了程序的耦合,便于程序的扩展和维护。
(2)将生产模块和消费模块的分隔,可使生产模块的运行不再依赖消费模块的执行,由同步改为异步执行并且都可支持并发,从而大大提高了程序的效率。
(3)生成者生产的数据存放在缓冲区中,消费者可以按照自己的逻辑来取出数据处理,从而可以有效避免消费模块任务执行负载不均的问题。

下面我将写一个最经典的例子

/** 
* @author 董硕: 
* @version 创建时间:2017年8月14日 下午7:20:49 
*  
*/

public class Baozi {
    private int count;//统计生产了多少包子

    public Baozi() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Baozi(int count) {
        super();
        this.count = count;
    }

    @Override
    public String toString() {
        return "Baozi [count=" + count + "]";
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
package com.ds.thread;
/** 
* @author 董硕: 
* @version 创建时间:2017年8月14日 下午7:17:04 
* 中间容器连接生产者与消费者之间联系
*/

public class ArrayPage {
    private int index=0;   //数组下标
    private Baozi []baozis=new Baozi[12];//数组的容器用来装包子
    /**生产包子 */
    public synchronized void  add(Baozi baozi) 
    {
        while(index==baozis.length)
        {
            System.out.println("笼子装满了");
            try {
                wait();                             //等待消耗包子
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        notify();                                   //继续生产包子
        baozis[index]=baozi;
        index++;
        System.out.println("已经生产"+baozi.getCount()+"个包子,笼中有"+index+"个包子");


    }
    /**消耗包子*/
    public synchronized void consume()
    {   
        while (index==0) {
            System.out.println("笼中无包子了");
            try {
                wait();                         //等待生产包子
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        notify();
        index--;
        Baozi baozi=    baozis[index];
        System.out.println("第"+baozi.getCount()+"包子被吃了,笼中还有"+index+"个包子");
    }

}
package com.ds.thread;
/** 
* @author 董硕: 
* @version 创建时间:2017年8月14日 下午7:43:35 
*  
*/
//生产者
class Produce extends Thread
{
    private ArrayPage arrayPage;
    private int  count=1;

    public Produce(ArrayPage arrayPage) {
        super();
        this.arrayPage = arrayPage;
    }
    @Override
    public void run() {
        while(true)
        {
            Baozi  baozi=new Baozi(count++);
            arrayPage.add(baozi);

        }
    }


}
class Consume extends Thread
{
    private ArrayPage arrayPage;

    public Consume(ArrayPage arrayPage) {
        super();
        this.arrayPage = arrayPage;
    }
    @Override
    public void run() {
        while(true)
        {
            arrayPage.consume();


        }
    }



}
public class MainMethod {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ArrayPage arrayPage=new ArrayPage();
        Produce produce=new Produce(arrayPage);
        Consume consume=new Consume(arrayPage);
        produce.start();
        consume.start();
    }

}

java线程生产者与消费者模型_第1张图片

你可能感兴趣的:(Java基础)