消费者生产者模型,超好理解

一、问题描述    

     生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。生产者生成一定量的数据放到缓冲区中,然后重复此过程;与此同时,消费者也在缓冲区消耗这些数据。生产者和消费者之间必须保持同步,要保证生产者不会在缓冲区满时放入数据,消费者也不会在缓冲区空时消耗数据。不够完善的解决方法容易出现死锁的情况,此时进程都在等待唤醒。
 

二、简化问题

      所谓生产者消费者问题,实际上主要是两类线程:

      一类是生产者线程用于生产数据

     一类是消费者线程用于消费数据

      还有一个类时用来保存数据的,通常会采用共享的数据区域,就像一个仓库一样

      生产者生产数据之后直接放置在共享数据库中,不需要关心消费者的行为

      消费者只需要从共享数据库中去获取数据,不需要关心生产者的行为

    

三、案例:

   生产者消费者案例中包含的类:

   奶箱类:提供存储牛奶和获取牛奶的操作

   生产者类:实现Runnable接口,重写run()方法,调用存储牛奶的操作

   消费者类:实现Runnable接口,重写run()方法,调用获取牛奶的操作

   测试类

代码实现:

//这个类就相当于共享的数据区

//在这个类中是代表装奶盒,里面最多能装10瓶奶
public class Box {
    private final int mile_max=10;
    //这就是一个容器,用来存放奶的
    LinkedList<Object> list=new LinkedList<>();
    //放奶
    public synchronized  void put(){
        //此时说明牛奶箱已经满了,不需要在进行产奶了
        while(list.size()+1>mile_max){
            System.out.println("【生产者:"+Thread.currentThread().getName()+"】仓库已满");
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //如果牛奶箱不满的话,就可以往牛奶箱中进行添加牛奶
        list.add(new Object());
        System.out.println("【生产者:"+Thread.currentThread().getName()+"】生产一个产品,现库存"+list.size());
        notifyAll();
    }
    //取奶
    public  synchronized  void get(){
        //如果牛奶箱中没有牛奶,让消费者进行等待,等待牛奶的生产
        while(list.size()==0){
            System.out.println("【消费者:"+Thread.currentThread().getName()+"】仓库已空");
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //如果牛奶箱中有牛奶,消费者可以进行拿牛奶操作
        list.remove();
        System.out.println("【消费者:"+Thread.currentThread().getName()+"】消费一个产品,现库存"+list.size());
       notifyAll();
    }
}
//这个类就是生产者类

//把牛奶往牛奶箱中进行放牛奶
public class Producer implements  Runnable {
    private  Box b;
   //这是生产者的无参和有参构造方法
    public  Producer(){}
    public  Producer(Box b){
        this.b=b;
    }

    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            b.put();
        }
    }
}
//这个类就是消费者类

//消费者进行消费牛奶
public class Customer implements  Runnable {
    private Box b;
    public Customer(){}
    //模拟消费者从箱子中进行消费牛奶
    public Customer(Box b){
        this.b=b;
    }

    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            b.get();
        }
    }
}
//下面是我的测试类

public class TestDemo {
    public static void main(String[] args) {
       //三个生产者三个消费者
        Box b=new Box();
        Producer p1=new Producer(b);
        Customer c1=new Customer(b);
        Producer p2=new Producer(b);
        Customer c2=new Customer(b);
        Producer p3=new Producer(b);
        Customer c3=new Customer(b);

        Thread t1=new Thread(p1);
        Thread t2=new Thread(p2);
        Thread t3=new Thread(p3);
        Thread t4=new Thread(c1);
        Thread t5=new Thread(c2);
        Thread t6=new Thread(c3);


        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
        t6.start();

    }
}

结果展示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值