创建一个消费者,告知生产者包子的种类和数量,调用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("包子已经吃完了,生产者开始生产包子");
}
}
}