> 文章列表 > 多线程之等待唤醒机制

多线程之等待唤醒机制

多线程之等待唤醒机制

生产者和消费者

核心思想:利用桌子来控制线程的执行。

 

消费者等待

消费者抢到了桌子的执行权,但是由于桌子上没有吃的,所以消费者需要先等待(wait) 

消费者等待时,cpu的执行权一定会被厨师拿走,制作好食物后,唤醒消费者来吃饭。

 生产者等待 

厨师抢到了执行权后,但是桌子上已经有食物了,厨师会进行等待(wait)

cpu的执行权会被消费者拿走,吃完之后,唤醒厨师继续做饭。

常见方法

 wait和notify方法注意事项

1、wait和notify方法必须同时由一个锁对象调用。这是因为notify唤醒的是使用同一个锁的对象调用wait方法的线程。

2、wait和notify方法都是属于Object类的方法。

锁对象可以是任何对象,而任意对象都是继承了Object类的。

3、wait和notify只能用在同步代码块或者同步方法中,这是因为只能通过锁对象调用这两个方法。

案例说明

//ThreadDemopublic class ThreadDemo {public static void main(String[] args) {//创建线程的对象cook1 cook1=new cook1();foodie1 foodie1=new foodie1();//给线程设置名字cook1.setName("厨师");foodie1.setName("吃货");//开启线程cook1.start();foodie1.start();}
}
//deskpublic class desk {/*作用:控制生产者和消费者的执行*///public static int foodFlag=0;//这里不是boolean类型是因为, 可能会有多条线程,为了通用性//总个数public static int count=10;//锁对象public static Object lock=new Object();}

 

//foodiepublic class foodie1 extends Thread{/*1、循环2、同步代码块3、判断共享数据是否到了末尾,是4、判断共享数据是否到了末尾,否*//*桌子作为等待唤醒机制的中枢机构*/@Overridepublic void run() {while(true){synchronized (desk.lock){if(desk.count==0){break;}else {//判断桌子上有咩有面条if(desk.foodFlag==0){//如果没有就等待,try {desk.lock.wait();//让当前线程和锁绑定} catch (InterruptedException e) {e.printStackTrace();}}else{//把吃的总数-1,desk.count--;//如果有就开吃System.out.println("消费者在进食,还可以吃"+desk.count+"碗");//吃完之后唤醒厨师继续做desk.lock.notifyAll();desk.foodFlag=0;}}}}}
}
//cookpublic class cook1 extends Thread{@Overridepublic void run() {/*1、循环2、同步代码块3、判断共享数据是否已经达到末尾。是的4、判断共享数据是否已经达到末尾。不是*/while(true){synchronized (desk.lock){if(desk.count==0){break;//如果所有的食物都被吃完了,结束线程}else{//判断桌子上是否有食物if(desk.foodFlag==1){//如果有,等待try {desk.lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}else {//如果没有,就制作食物System.out.println("厨师做了一碗面条");//修改桌子上的食物状态desk.foodFlag=1;//叫醒等待的消费者开吃desk.lock.notifyAll();}}}}}
}