线程的等待与唤醒机制:
什么是等待唤醒机制????
线程的等待与唤醒机制主要解决的问题:
注意的问题:
两线程必须使用同步代码块包裹起来,保证等待与唤醒只能有一个执行。
同步使用的锁对象必须保证唯一。
只有锁对象才能调用wait()和notify()
===================================================
线程的等待与唤醒案例:
包与类的放置的位置:
public class demo_w_m {
public static void main(String[] args) {
//创建包子对象
baozi bz = new baozi();
//创建包子铺线程,
new baozipu(bz).start();
//创建吃货线程
new chihuo(bz).start();
}
}
public class baozipu extends Thread {
//成员变量的位置创建一个 包子 的成员变量作为资源;
private baozi bz;
public baozipu(baozi bz) {
this.bz = bz;
}
public void run() {
int count = 0;
while (true) {
synchronized (bz) {
//如果有包子
if (bz.flag == true) {
try {
//有包子就等待不做包子
System.out.println("老板:还有包子,我先放入释放锁,进等待池");
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 + "包子");
//包子铺生产包子,让做包子进程睡2秒中,2秒中的时间在做包子
try {
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
//2秒之后,做好了包子,这个时候修改包子的状态,为 ‘有包子’,有包子了就唤醒吃货线程,
// 让其处于就绪状态,这个时候当前做包子线程的对象锁还没释放
bz.flag=true;
bz.notify();
System.out.println("包子铺老板:嘿嘿,包子铺已经生产好了:"+bz.pi + bz.xian);
}
}
}
}
public class chihuo extends Thread {
private baozi bz;
public chihuo(baozi bz){
this.bz=bz;
}
public void run(){
while (true){
synchronized (bz){
//没有包子
if(bz.flag==false){
try {
//没有包子了就让当前吃货线程处于等待。
System.out.println("吃货:包子吃完了,我停止吃包子,我进等待池");
System.out.println("==================================");
bz.wait();
}catch (InterruptedException e)
{
e.printStackTrace();
}
}
//以下是线程被唤醒之后的程序
System.out.println();
System.out.println("吃货:恩恩,老板,我现在来吃"+bz.pi+bz.xian+"包子");
//包子吃完了,唤醒做包子线程
bz.flag=false;
bz.notify();//唤醒进程,让其处于就绪状态,一旦这里进程释放锁,被唤醒的线程就继续执行。(就是唤醒吃货的线程,但是还要等到包子铺的线程上的对象资源锁被释放了才能让吃货线程运行起来)
System.out.println("吃货:哇塞,包子已经吃完啦,老板,在做些包子"+bz.pi+bz.xian+"包子");
}
}
}
}
注意,这里两边都用了死循环的方式,程序运行如下: