javaSE进阶练习——多线程等待唤醒练习

该博客介绍了如何使用Java实现一个多线程同步的场景,模拟顾客和厨师之间的交互。通过桌面上的蛋糕作为共享资源,利用`synchronized`关键字和`wait()`、`notifyAll()`方法确保线程间的正确通信。顾客线程在无蛋糕时等待,厨师线程在制作完蛋糕后唤醒顾客。整个过程持续到所有蛋糕吃完为止。
摘要由CSDN通过智能技术生成

经典等待唤醒

需求分析:

       有一个桌子,桌子上有一个蛋糕,当顾客线程先抢到CPU,则先执行顾客线程,上锁,首先看桌子,若有蛋糕顾客去吃,吃完了唤醒厨师线程去抢CPU做蛋糕,自己再继续抢CPU;若没蛋糕则等待,解锁,让厨师运行厨师线程做蛋糕。若厨师先抢到CPU看到桌子,若有蛋糕,厨师等待,解锁,把cpu让给顾客,执行顾客线程;若无蛋糕,厨师做蛋糕,做完蛋糕唤醒顾客线程去抢CPU,自己再继续抢CPU。顾客厨师反复抢CPU,直到达到run结束的条件。
       若唤醒其它线程后,自己又抢到CPU,则继续唤醒,再抢,直到被唤醒的线程抢到CPU。

tips:
      wait()使当前线程等待(不参与抢cpu),并且释放lock,让其它线程可以访问同步代码块。
      两个线程共用同一把锁,执行线程时操作同一资源。

详细流程图如下:

                                                                   图1 流程图

详细代码:

1.厨师线程

public class Cook extends Thread{
    @Override
    public void run() {
        while (true){
//            加锁
            synchronized (Desk.obj){
//                线程结束表示
                if(Desk.count==0){
                    System.out.println("营业结束");
                    break;}
//                判断有无蛋糕
                if(Desk.flag==0){
//                    没有蛋糕,做一个
                    Desk.flag=1;
                    System.out.println("厨师做蛋糕");
//                    唤醒顾客吃
                    Desk.obj.notifyAll();
                }else {
//                    有蛋糕,等待顾客eater唤醒
                    try {
                        Desk.obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

2.顾客线程

public class Eater extends Thread {
    @Override
    public void run() {
        while (true){
//            首先加锁
            synchronized (Desk.obj){
//                剩余蛋糕数作为结束线程的判断
                if(Desk.count==0){
                    System.out.println("营业结束");
                    break;}
//                判断桌子上有无吃的
                if(Desk.flag==0){
//                    没有,则等待厨师唤醒
                    System.out.println("顾客等蛋糕");
                    try {
                        Desk.obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                else {
//                    有,则吃一个
                    Desk.flag=0;
//                    修改桌子上的状态
                    System.out.println("顾客吃了一个,还剩"+--Desk.count+"个");
//                    唤醒厨师做
                    Desk.obj.notifyAll();
                }
            }
        }
    }
}

3.桌子

public class Desk {

    public static int count=10;//总共蛋糕数

    public static int flag=0;//0 表示桌子上没有蛋糕,1表示桌子上有蛋糕

    static Object obj=new Object();//锁对象
}

4.测试类

public class eatCake {
    public static void main(String[] args) {
//    创建顾客和厨师线程对象
        Eater eater=new Eater();
        Cook cook=new Cook();
//    启动线程
        cook.start();
        eater.start();
    }


}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值