-
需求
-
将Desk类中的变量,采用面向对象的方式封装起来
-
生产者和消费者类中构造方法接收Desk类对象,之后在run方法中进行使用
-
创建生产者和消费者线程对象,构造方法中传入Desk类对象
-
开启两个线程
-
-
代码实现
主入口Demo: -
public class Demo { public static void main(String[] args) { /*消费者步骤: 1,判断桌子上是否有汉堡包。 2,如果没有就等待。 3,如果有就开吃 4,吃完之后,桌子上的汉堡包就没有了 叫醒等待的生产者继续生产 汉堡包的总数量减一*/ /*生产者步骤: 1,判断桌子上是否有汉堡包 如果有就等待,如果没有才生产。 2,把汉堡包放在桌子上。 3,叫醒等待的消费者开吃。*/ Desk desk = new Desk(); Foodie f = new Foodie(desk); Cooker c = new Cooker(desk); f.start(); c.start(); } }
共享平台Desk:
-
public class Desk { //定义一个标记 //true 就表示桌子上有汉堡包的,此时允许吃货执行 //false 就表示桌子上没有汉堡包的,此时允许厨师执行 //public static boolean flag = false; private boolean flag; //汉堡包的总数量 //public static int count = 10; //以后我们在使用这种必须有默认值的变量 // private int count = 10; private int count; //锁对象 //public static final Object lock = new Object(); private final Object lock = new Object(); public Desk() { this(false,10); // 在空参内部调用带参,对成员变量进行赋值,之后就可以直接使用成员变量了 } public Desk(boolean flag, int count) { this.flag = flag; this.count = count; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public Object getLock() { return lock; } @Override public String toString() { return "Desk{" + "flag=" + flag + ", count=" + count + ", lock=" + lock + '}'; } } public class Cooker extends Thread { private Desk desk; public Cooker(Desk desk) { this.desk = desk; } // 生产者步骤: // 1,判断桌子上是否有汉堡包 // 如果有就等待,如果没有才生产。 // 2,把汉堡包放在桌子上。 // 3,叫醒等待的消费者开吃。 @Override public void run() { while(true){ synchronized (desk.getLock()){ if(desk.getCount() == 0){ break; }else{ //System.out.println("验证一下是否执行了"); if(!desk.isFlag()){ //生产 System.out.println("厨师正在生产汉堡包"); desk.setFlag(true); desk.getLock().notifyAll(); }else{ try { desk.getLock().wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } }
消费者Foodie:
-
public class Foodie extends Thread { private Desk desk; public Foodie(Desk desk) { this.desk = desk; } @Override public void run() { // 1,判断桌子上是否有汉堡包。 // 2,如果没有就等待。 // 3,如果有就开吃 // 4,吃完之后,桌子上的汉堡包就没有了 // 叫醒等待的生产者继续生产 // 汉堡包的总数量减一 //套路: //1. while(true)死循环 //2. synchronized 锁,锁对象要唯一 //3. 判断,共享数据是否结束. 结束 //4. 判断,共享数据是否结束. 没有结束 while(true){ synchronized (desk.getLock()){ if(desk.getCount() == 0){ break; }else{ //System.out.println("验证一下是否执行了"); if(desk.isFlag()){ //有 System.out.println("吃货在吃汉堡包"); desk.setFlag(false); desk.getLock().notifyAll(); desk.setCount(desk.getCount() - 1); }else{ //没有就等待 //使用什么对象当做锁,那么就必须用这个对象去调用等待和唤醒的方法. try { desk.getLock().wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } }
生产者Cooker:
-
public class Cooker extends Thread { private Desk desk; public Cooker(Desk desk) { this.desk = desk; } // 生产者步骤: // 1,判断桌子上是否有汉堡包 // 如果有就等待,如果没有才生产。 // 2,把汉堡包放在桌子上。 // 3,叫醒等待的消费者开吃。 @Override public void run() { while(true){ synchronized (desk.getLock()){ if(desk.getCount() == 0){ break; }else{ //System.out.println("验证一下是否执行了"); if(!desk.isFlag()){ //生产 System.out.println("厨师正在生产汉堡包"); desk.setFlag(true); desk.getLock().notifyAll(); }else{ try { desk.getLock().wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } }
第十五章生产者与消费者案例代码
最新推荐文章于 2024-09-27 00:45:01 发布