调用wait和notify方法需要注意的细节(重要)
1. wait方法与notify方法必须要由**同一个锁对象调用**。因为:对应的锁对象可以通过notify唤醒使用同一个锁对象调用的wait方法后的线程。
2. wait方法与notify方法是属于Object类的方法的。因为:锁对象可以是任意对象,而任意对象的所属类都是继承了Object类的。
3. wait方法与notify方法必须要在同步代码块或者是同步函数中使用。因为:必须要通过锁对象调用这2个方法。
具体代码
包子
public class BaoZi {
//皮
String pi ;
//馅
String xian;
//包子的状态:有 true 没有 false ,设置初始值为false 没有包子
Boolean flag = false;
}
生产者:包子铺
public class BaoZiPu extends Thread{
//1.需要在成员位置创建一个包子变量
private BaoZi bz;
//2.使用带参数构造方法,为这个包子变量赋值
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+"包子,吃货可以开吃了");
}
}
}
}
消费者:吃货
public class ChiHuo extends Thread {
//1.需要在成员位置创建一个包子变量
private BaoZi bz;
//2.使用带参数构造方法,为这个包子变量赋值
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("----------------");
}
}
}
}
运行的demo
public class Demo{
public static void main(String[] args){
//创建包子对象
BaoZi bz = new BaoZi();
//创建包子铺线程,开启,生产包子
new BaoZiPu(bz).start();
//创建吃货线程,开启,吃包子
new ChiHuo(bz).start();
}
}
案例分析
写的思路
生产者:
1. 考虑满足了要求,就进行使用wait();
2. 没满足最终的要求,就生产,最后使用notify()
消费者:
1. 考虑满足了要求,就进行使用wait();
2. 没满足最终的要求,就生产,最后使用notify()