JAVA简单实现多线程的生产者和消费者模型

Java 多线程中的生产者消费者模型是一个很经典的示例。

什么是生产者消费者模型呢?

所谓的生产者消费者模型,是通过一个容器来解决生产者和消费者的强耦合问题。

举个例子,我们去工厂拿货,工厂也在给我们生产,这就必然存在一个中间容器,我们可以把这个容器想象成
是一个仓库。当我们想要拿货的时候,我们就去仓库查看有没有生产好的货物,如果货架是空的,工厂就要生
产货物,此时我们作为消费者就需要等待工厂生产商品;当工厂生产的商品太多了爆满了仓库,工厂就可以通
知作为消费者的我们去仓库拿货,这样不停循环。在这个循环过程中,我们不是直接接触工厂的,而是去仓库
拿货,工厂也并不是生产好了商品就直接给到我们,而是将生产好的商品放在仓库中,工厂和我们是不会进行
直接接触的。所谓的仓库,我们可以想象成一个queue(队列),这个队列就是把我们和工厂给解耦,这就是
生产者消费者模型。

生产者消费者模型能解决什么问题?

显而易见,生产者消费者模型能将生产者和消费者彻底解耦,并且,我们可以不在乎生产者的生产速度,以及
消费者的消费速度。

生产者消费者模型代码示例:

先定义商品类

package goods;

/**
 * 商品类
 */
public class Goods {

    private String name; // 商品的名称
    private int price; // 商品的价格

    public Goods(String name,int price){
        this.name = name;
        this.price = price;
    }

    public String toString(){
        return "name="+name+",price="+price;
    }
}

生产者:

package goods;

/**
 * 生产者
 * fazcube
 */
public class Producer implements Runnable{

    private Goods goods;

    @Override
    public void run() {
        while (true){
            try {
            	//控制一下间隔时间
                Thread.sleep(1000);
                synchronized (Start.queue){
                    goods = new Goods("商品",5);
                    //如果仓库(queue)的大小大于等于仓库最大的数量,那么就让线程wait
                    if(Start.queue.size() >= Start.MAX_COUNT){
                        System.out.println(Thread.currentThread().getName()+"说:仓库爆满啦!快点来拿货!");
                        Start.queue.wait();
                    }else{
                    	//如果仓库还有位置,那么就继续生产商品。
                        Start.queue.add(goods);
                        System.out.println(Thread.currentThread().getName()+"生产了一个商品");
                    }
                    //将等待的线程唤醒
                    Start.queue.notify();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

消费者:

package goods;

/**
 * 消费者
 * fazcube
 */
public class Consumer implements Runnable{

    @Override
    public void run() {
        while (true){
            try {
            	//控制一下间隔时长
                Thread.sleep(1000);
                synchronized (Start.queue){
                	//如果
                    if(!Start.queue.isEmpty()){
                        Start.queue.poll();
                        System.out.println(Thread.currentThread().getName()+"消费了一个商品,还剩:"+Start.queue.size()+"个");
                    }else{
                        System.out.println(Thread.currentThread().getName()+"说:仓库里面没有货啦!快点生产!");
                        Start.queue.wait();
                    }
                    //将等待的线程唤醒
                    Start.queue.notify();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

启动类:

package goods;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

public class Start {

    /** 设置最大存货量 */
    public static int MAX_COUNT = 5;
    /** 消费者的数量 */
    public static int CONSUMER_COUNT = 5;
    /** 生产者的数量 */
    public static int PRODUCER_COUNT = 5;
    /** 创建一个queue来存放商品 */
    public static Queue<Goods> queue = new ArrayBlockingQueue<>(MAX_COUNT);

    public static void main(String[] args) {
        Consumer consumer = new Consumer();
        Producer producer = new Producer();

        for(int i=0;i<PRODUCER_COUNT;i++){
            Thread thread = new Thread(producer,"生产者"+i+"号");
            thread.start();
        }
        for(int m=0;m<CONSUMER_COUNT;m++){
            Thread thread = new Thread(consumer,"消费者"+m+"号");
            thread.start();;
        }
    }
}

启动截图:

生产者消费者模型运行截图
生产者消费者模型

如有错误还请指教,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值