package com.shopping.test;public class ShaoKao { //串 String chuan; //肉 String rou; //烧烤的状态,初始状态为没有烧烤 boolean flag = false; public String getChuan() { return chuan; } public void setChuan(String chuan) { this.chuan = chuan; } public String getRou() { return rou; } public void setRou(String rou) { this.rou = rou; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; }}
下面是生产者
package com.shopping.test;/* * 注意: * 烧烤铺线程和吃货线程关系--->通信(互斥) * 必须使用同步技术保证两个线程只能有一个在执行 * 锁对象必须保证唯一,可以使用烧烤对象作为锁对象 * 烧烤铺类和吃货类就需要把烧烤对象作为参数传进去 * 1. 需要在成员位置创建一个烧烤变量 * 2. 使用带参数构造方法,为这个烧烤变量赋值 */public class ShaoKaoPu extends Thread { //1. 需要在成员位置创建一个烧烤变量,作为锁对象 private ShaoKao bz; //2. 使用带参数构造方法,为这个烧烤变量赋值 public ShaoKaoPu(ShaoKao bz) { this.bz = bz; } //设置线程任务(run), 生产烧烤 public void run() { //定义一个变量,这个变量决定到底要做什么馅的烧烤 int count = 0; //死循环,让烧烤铺一直生产烧烤 while(true) { //必须使用同步技术保证两个线程只能有一个在执行 synchronized(bz) { //对烧烤的状态进行判断 if(bz.flag == true) { //已经有烧烤了,不用生产,烧烤铺调用wait方法进入等待状态 try { bz.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //被吃货唤醒之后,证明没有烧烤了,又要开始生产烧烤 //增加一些趣味性:交替生产烧烤 if(count % 2 == 0) { //生产 羊肉烤串 bz.chuan = "大串"; bz.rou = "羊肉"; }else { //生产 牛肉大葱馅 bz.chuan = "大串"; bz.rou = "羊肉"; } count++; System.out.println("烧烤铺正在生产:" + bz.chuan + bz.rou + "烧烤"); //生产烧烤需要3秒钟 try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } //烧烤铺生产好了烧烤,修改烧烤的状态为true有 bz.flag = true; //唤醒吃货线程起来吃烧烤 bz.notify(); //烧烤铺已经生产好了烧烤 System.out.println("烧烤铺已经生产好了" + bz.chuan + bz.rou + "烧烤" + "吃货可以开始吃了"); } } }}
消费者
package com.shopping.test;public class ChiHuo extends Thread{ //1. 需要在成员位置创建一个烧烤变量,作为锁对象 private ShaoKao bz; //2. 使用带参数构造方法,为这个烧烤变量赋值 public ChiHuo(ShaoKao bz) { this.bz = bz; } //设置线程任务(run), 吃烧烤 public void run() { //死循环,让吃货一直吃烧烤 while(true) { //必须使用同步技术保证两个线程只能有一个在执行 synchronized(bz) { //对烧烤的状态进行判断 if(bz.flag == false) { //发现没有烧烤,吃货调用wait方法进入等待状态,等烧烤铺做好烧烤 try { bz.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //被烧烤铺唤醒之后,证明有烧烤吃了 System.out.println("吃货正在吃:" + bz.chuan + bz.rou + "的烧烤"); //吃货吃完烧烤 //修改烧烤的状态为false没有 bz.flag = false; //吃货唤醒烧烤铺线程,继续生产烧烤 bz.notify(); System.out.println("吃货已经把:" + bz.chuan + bz.rou + "的烧烤吃完了"); System.out.println("---------------------------------------------------------------------------"); } } }}
测试:
package com.shopping.test;public class Test { public static void main(String[] args) { //创建烧烤对象,作为锁对象 ShaoKao bz = new ShaoKao(); //创建烧烤铺线程 new ShaoKaoPu(bz).start(); //开启吃货线程 new ChiHuo(bz).start(); }}
输出的是:
烧烤铺正在生产:大串羊肉烧烤
烧烤铺已经生产好了大串羊肉烧烤吃货可以开始吃了吃货正在吃:大串羊肉的烧烤吃货已经把:大串羊肉的烧烤吃完了---------------------------------------------------------------------------烧烤铺正在生产:大串羊肉烧烤烧烤铺已经生产好了大串羊肉烧烤吃货可以开始吃了吃货正在吃:大串羊肉的烧烤吃货已经把:大串羊肉的烧烤吃完了---------------------------------------------------------------------------烧烤铺正在生产:大串羊肉烧烤烧烤铺已经生产好了大串羊肉烧烤吃货可以开始吃了吃货正在吃:大串羊肉的烧烤吃货已经把:大串羊肉的烧烤吃完了---------------------------------------------------------------------------