包子类(锁对象)
包子铺类(生产者)
吃货类(消费者)
简单描述:
刚刚开始的包子状态是没有(即没有包子),所以唤醒包子铺线程去生产包子,生产完包子后,修改包子状态为有,唤醒吃货线程去吃包子,包子铺线程进入等待状态;吃货吃完包子后,修改包子状态为没有,唤醒包子铺线程,吃货线程进入等待状态。为了保证线程安全,使用了同步代码块,用包子类作为锁对象。
while(true){}
无限循环,让包子铺一直生产包子,吃货一直吃包子。
BaoZi.java
public class BaoZi {
// 皮
String pi;
// 馅
String xian;
// 包子的状态:有 true ,没有 false ,设置初始值为 false 没有包自
boolean flag = false;
}
BaoZiPu.java
public class BaoZiPu extends Thread{
// 需要在成员位置创建一个包子变量
private BaoZi bz;
// 使用带参数构造方法,为这个包子变量附值
public BaoZiPu(BaoZi bz){
this.bz = bz;
}
// 设置线程任务(run):生产包子
@Override
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.pi = "薄皮";
bz.xian = "三鲜馅";
} else {
// 生产 冰皮牛肉大葱包子
bz.pi = "冰皮";
bz.xian = "牛肉大葱";
}
count++;
System.out.println("包子铺正在生产:" + bz.pi + bz.xian + "包子");
// 生产包子需要3秒钟
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 包子铺生产好了包子
// 修改包子的状态为 true 有
bz.flag = true;
// 唤醒吃货线程,让吃货线程吃包子
bz.notify();
System.out.println("包子铺已经生产:" + bz.pi + bz.xian + "包子,吃货可以开始吃");
}
}
}
}
ChiHuo.java
public class ChiHuo extends Thread{
// 需要在成员位置创建一个包子变量
private BaoZi bz;
// 使用带参数构造方法,为这个包子变量附值
public ChiHuo(BaoZi bz){
this.bz = bz;
}
// 设置线程任务(run):吃包子
@Override
public void run() {
// 使用死循环,让吃货一直吃包子
while(true){
// 必须同时同步技术保证两个线程只能一个在执行
synchronized(bz){
// 对包子的状态进行判断
if (bz.flag == false){
// 吃货调用 wait 方法进入等待状态
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 被唤醒之后执行的代码,吃包子
System.out.println("吃货正在吃:"+bz.pi+bz.xian+"包子");
// 吃货吃完包子
// 修改包子的状态为 false 没有
bz.flag = false;
// 吃货唤醒包子铺线程,生产包子
bz.notify();
System.out.println("吃货已经把:"+bz.pi+bz.xian+"的包子吃完了,包子铺开始生产包子");
System.out.println("-----------------------------");
}
}
}
}
DemoTest.java
public class DemoTest {
public static void main(String[] args) {
System.out.println("-------");
BaoZi bz = new BaoZi();
// 创建包子铺线程,开启,生产包子
new BaoZiPu(bz).start();
// 创建吃货线程,开启,吃包子
new ChiHuo(bz).start();
}
}