生产者消费者案例(重点之重点)
生产者消费者案例
- 一 案例讲解
- 二 以图文和代码内容形式讲解
-
- Box类
- Producer类
- Customer类
- BoxDemo类
一 案例讲解
- 奶箱类(Box):定义一个成员变量,表示第X瓶奶,提供存储牛奶和获取牛奶的操作。
- 生产者类(Producer):实现Runnable接口,重写run()方法,调用存储牛奶的操作。
- 消费者类(Producer):实现Runnable接口,重写run()方法,调用获取牛奶的操作。
- 测试类(BoxDemo):里面有main方法,main方法中的代码步骤如下:
- 创建奶箱对象,这是共享数据区域
- 创建生产者对象,把奶箱对象作为构造方法参数传递,因为这个类中要调用存储牛奶的操作
- 创建消费者对象,把奶箱对象作为构造方法参数传递,因为这个类中要调用获取牛奶的操作
- 创建2个线程对象,分别把生产者对象和消费者对象作为构造方法参数传递
- 启动线程
二 以图文和代码内容形式讲解
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(); }}
输出的内容: