> 文档中心 > 生产者消费者案例(重点之重点)

生产者消费者案例(重点之重点)

生产者消费者案例

  • 一 案例讲解
  • 二 以图文和代码内容形式讲解
    • Box类
    • Producer类
    • Customer类
    • BoxDemo类

一 案例讲解

  • 奶箱类(Box):定义一个成员变量,表示第X瓶奶,提供存储牛奶和获取牛奶的操作。
  • 生产者类(Producer):实现Runnable接口,重写run()方法,调用存储牛奶的操作。
  • 消费者类(Producer):实现Runnable接口,重写run()方法,调用获取牛奶的操作。
  • 测试类(BoxDemo):里面有main方法,main方法中的代码步骤如下:
    1. 创建奶箱对象,这是共享数据区域
    2. 创建生产者对象,把奶箱对象作为构造方法参数传递,因为这个类中要调用存储牛奶的操作
    3. 创建消费者对象,把奶箱对象作为构造方法参数传递,因为这个类中要调用获取牛奶的操作
    4. 创建2个线程对象,分别把生产者对象和消费者对象作为构造方法参数传递
    5. 启动线程

二 以图文和代码内容形式讲解

Box类

package Demo;public class Box{    private int milk;//建立牛奶箱变量值    private boolean state = false;//定义一个生产牛奶的状态,此时未生产牛奶(说明有牛奶生产了)    //存储牛奶    public synchronized void put(int milk){ if (state){//如果有牛奶,那么我就不生产牛奶!!给送奶工     try {  wait();//如果有牛奶,那么我就不生产牛奶给送奶工,此时会让调用put方法的类的线程等待下一个调用get方法的类的线程     } catch (InterruptedException e) {  e.printStackTrace();     } } //当没牛奶,我就开始生产牛奶,然后给送奶工 this.milk = milk; System.out.println("送奶工送了"+this.milk+"个牛奶"); //生产完毕之后,修改奶箱状态 state=true;//此时(公共)全局变量值改变 //唤醒其他线程 notifyAll();    }    //获取牛奶    public synchronized void get(){ if (!state){//如果我没收到牛奶,那么肯定要生产牛奶,此时开始生产牛奶     try {  wait();//如果消费者没有获取到牛奶,那么我就生产牛奶给送奶工,此时会让调用get方法的类的线程等待下一个调用put方法的类的线程     } catch (InterruptedException e) {  e.printStackTrace();     } } //当我获取到牛奶,此时不用生产牛奶 System.out.println("消费者获取了"+this.milk+"个牛奶"); state=false;//此时(公共)全局变量值改变 //唤醒其他线程 notifyAll();    }}

一定要看完代码后理解这句话:

  • state是全局(公共)变量值,代表是否生产牛奶
  • void put(int milk)方法中里面"if(state)"代表的是如果有牛奶,那么我就不生产牛奶!!给送奶工,里面有"wait()"此时会让调用put方法的类的线程等待下一个调用get方法"执行一半"的类的线程
  • void get()方法中里面"if(!state)"代表的是如果我没收到牛奶,那么肯定要生产牛奶,此时开始生产牛奶!!,里面有"wait()"此时会让调用get方法的类的线程等待下一个调用put方法"执行一半"的类的线程
  • 吴含

Producer类

package Demo;public class Producer implements Runnable {    private Box box;    public Producer(Box box) { this.box = box;    }    @Override    public void run() { for (int i = 1; i <= 5; i++) {     box.put(i); }    }}

通过将共享数据公共对象用有参构造方法进行传递,确保对象地址的一样

Customer类

package Demo;public class Customer implements Runnable {    private Box box;    public Customer(Box box) { this.box = box;    }    @Override    public void run() { while (true) {     box.get(); }    }}

通过将共享数据公共对象用有参构造方法进行传递,确保对象地址的一样

BoxDemo类

package Demo;public class BoxDemo {    public static void main(String[] args) { //创建奶箱对象,这是共享数据区域 Box box = new Box(); //创建生产者对象,把奶箱对象作为构造方法参数传递,因为这个类中要调用存储牛奶的操作 Producer p = new Producer(box); //创建消费者对象,把奶箱对象作为构造方法参数传递,因为这个类中要调用获取牛奶的操作 Customer c = new Customer(box); //创建2个线程对象,分别把生产者对象和消费者对象作为构造方法参数传递 Thread t1 = new Thread(p); Thread t2 = new Thread(c); //启动线程 t1.start(); t2.start();    }}

输出的内容:
生产者消费者案例(重点之重点)