Java等待唤醒机制

创建一个消费者,告知生产者包子的种类和数量,调用wait方法,放弃cpu的执行,进入到无限等待状态。
创建一个生产者,花了5秒做包子,做好包子之后调用notify()方法,唤醒顾客吃包子。
注意:
顾客和老板线程必须使用同步代码块包裹起来,保证等待和唤醒只能有一个在执行
同步使用的锁对象必须保证唯一
只有锁对象才能调用wait和notify

public abstract class WaitAndNotify implements Runnable{
	public static void main(String[] args) {
		Object obj = new Object();//创建唯一的锁对象
		
		new Thread() {//创建消费者线程
			@Override
			public void run() {
				synchronized(obj) {//使用同步代码块进行包裹
					System.out.println("给生产者说生产什么样的包子");
					try {
						obj.wait();//锁对象使用wait方法,等待回复
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("开始吃包子");//唤醒之后的方法
				}
			}
		}.start();
		
		new Thread() {//创建生产者线程
			@Override
			public void run() {
				try {
					Thread.sleep(5000);//5秒钟后通知消费者
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(obj) {
					System.out.println("告诉消费者可以吃包子了");
					obj.notify();
				}
			}
		}.start();
		
	}
}
//给生产者说生产什么样的包子
//告诉消费者可以吃包子了
//开始吃包子

使用Timewaiting有两种方式:
1:使用sleep(long m) 方法,在毫秒值结束之后,线程睡醒进入到Runable、Block状态。
2:使用wait(long m)方法,wait方法如果在毫秒值结束之后,还没有被notify()唤醒,就会自动醒来,然后进入到Runable/Block状态。

唤醒的方法:
1:notify();唤醒单个线程
2:notifyAll()唤醒等待的所有线程。

public abstract class WaitAndNotify implements Runnable{
	public static void main(String[] args) {
		Object obj = new Object();//创建唯一的锁对象
		
		new Thread() {//创建消费者线程
			@Override
			public void run() {
				while(true) {
					synchronized(obj) {//使用同步代码块进行包裹
						System.out.println("海绵宝宝给生产者说生产什么样的包子");
						try {
							obj.wait();//锁对象使用wait方法,等待回复
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						System.out.println("海绵宝宝开始吃包子");//唤醒之后的方法
					}
				}
			}
		}.start();
		
		new Thread() {//创建消费者线程
			@Override
			public void run() {
				while(true) {
					synchronized(obj) {//使用同步代码块进行包裹
						System.out.println("派大星给生产者说生产什么样的包子");
						try {
							obj.wait();//锁对象使用wait方法,等待回复
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						System.out.println("派大星开始吃包子");//唤醒之后的方法
					}
				}
			}
		}.start();
		new Thread() {//创建生产者线程
			@Override
			public void run() {
				while(true) {
					try {
						Thread.sleep(5000);//5秒钟后通知消费者
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					synchronized(obj) {
						System.out.println("告诉消费者可以吃包子了");
						obj.notifyAll();
					}
				}
			}
		}.start();
	}
}
海绵宝宝给生产者说生产什么样的包子
派大星给生产者说生产什么样的包子
告诉消费者可以吃包子了
派大星开始吃包子
海绵宝宝开始吃包子

栗子:
创建包子对象:

public class Baozi {
	private String pi;
	private String xian;
	public boolean flag=false;//设置包子的初始值
	public Baozi() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Baozi(String pi, String xian) {
		super();
		this.pi = pi;
		this.xian = xian;
	}
	public String getPi() {
		return pi;
	}
	public void setPi(String pi) {
		this.pi = pi;
	}
	public String getXian() {
		return xian;
	}
	public void setXian(String xian) {
		this.xian = xian;
	}
}

创建包子铺对象

public class BaoZiPu extends Thread{
	private Baozi bz;

	public BaoZiPu(Baozi bz) {
		super();
		this.bz = bz;
	}
	@Override
	public void run() {
		int count = 0;
		// TODO Auto-generated method stub
		synchronized(bz) {
			if(bz.flag==true) {//有包子就等待
				try {
					bz.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(count%2==0) {
				bz.setPi("薄皮");
				bz.setXian("草莓馅");
			}else {
				bz.setPi("厚皮");
				bz.setXian("巧克力馅");
			}
			count++;
			System.out.println("正在生产"+bz.getPi()+bz.getXian()+"包子");
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			bz.flag=true;//修改包子的状态
			bz.notify();//通知可以开始吃包子
			System.out.println("包子已经生产好了,可以开始吃了");
		}
	}
}

创建吃的线程

public class Eat extends Thread{
	private Baozi bz;
	public Eat(Baozi bz) {
		super();
		this.bz = bz;
	}
	public void run() {
		synchronized (bz) {
			if(bz.flag==false) {
				try {
					bz.wait();//没有包子就等待,等到通知有包子就唤醒
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			System.out.println("吃货正在吃"+bz.getPi()+bz.getXian()+"包子");
			bz.flag=true;
			bz.notify();//通知生产者开始生产包子
			System.out.println("包子已经吃完了,生产者开始生产包子");
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值