(3)JavaSE:等待唤醒机制两种实现方法-阻塞队列

在这里插入图片描述
桌子上有面条-》吃货执行
桌子上没面条-》生产者制造执行
在这里插入图片描述

1、消费者等待

消费者先抢到CPU执行权,发现桌子上没有面条,于是变成等待wait状态,并释放CPU执行权,此时的CPU肯定会被厨师抢到,初始开始做面条,当厨师做完后会对吃货进行提示,notify唤醒吃货来吃。
在这里插入图片描述
在这里插入图片描述

2、生产者等待

厨师先抢到CUP执行权,但是桌子上有面条,就不能再制作面条,只能等待消费者吃完面条才能做,消费者吃完后需要唤醒厨师继续做
在这里插入图片描述
代码逻辑:
在这里插入图片描述
厨师:

public class Cook extends Thread{
    @Override
    public void run() {
        //1循环
        //2同步代码块
        //3共享数据是否到末尾,Yes
        //4共享数据是否到末尾,No
        while (true){
            synchronized (Desk.lock){
                if (Desk.count==0){
                    break;//10碗吃完
                }else {
                    //厨师的核心逻辑
                    //01判断桌子上是否有食物
                    if (Desk.foodflag==1){
                        //02有食物就等待
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }else {
                        //03没有
                        System.out.println(Thread.currentThread().getName()+"制作食物");
                        //04改变桌子状态
                        Desk.foodflag=1;
                        //05唤醒消费者吃
                        Desk.lock.notifyAll();
                    }

                }
            }


        }
    }
}

吃货:

public class Customer extends Thread{
    @Override
    public void run() {
        while (true){
            synchronized (Desk.lock){
                if (Desk.count==0){
                    break;//10碗吃完
                }else {
                    //吃货的核心逻辑
                    /*
                    * 1.判断桌子上有无面条
                    * 2.没有:自己等待,
                    * 3.有:吃完,并唤醒厨师做面条,count--
                    * 4.修改桌子状态*/
                    if (Desk.foodflag==0){//1.判断桌子上有无面条
                        try {
                            Desk.lock.wait();//2.没有:自己等待,
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }else {//3.有:吃完,并唤醒厨师做面条,count--
                        Desk.count--;
                        System.out.println(Thread.currentThread().getName()+"还能再吃"+Desk.count+"碗");
                        Desk.lock.notifyAll();
                        //4.修改桌子状态
                        Desk.foodflag=0;

                    }

                }
            }


        }
    }
}

桌子:

public class Desk {
    //通过变量来控制 0:没食物  1:有食物
    public static int foodflag=0;

    //总个数,最多做十碗
    public static int count=10;

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

//测试类

public class Test {
    public static void main(String[] args) {
        Customer customer = new Customer();
        Cook cook = new Cook();

        customer.setName("吃货");
        cook.setName("厨师");

        customer.start();
        cook.start();
    }
}

3、阻塞队列实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

接口无法new对象,只能通过两个实现类,第一个可以自定义队列长度。
注意:生产者与消费者必须针对同一个阻塞队列,阻塞队列可以创建在测试类中
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
厨师:

public class Cook extends Thread{
    ArrayBlockingQueue<String> queue;
    //创建构造函数,创建对象的时候进行赋值,指定同一个阻塞队列
    public Cook(ArrayBlockingQueue<String> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        while (true){
            try {
                queue.put("面条");
                System.out.println("厨师做了一碗面条");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

消费者:

public class Customer extends Thread{
    ArrayBlockingQueue<String> queue;

    public Customer(ArrayBlockingQueue<String> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        while (true){
            try {
                String food=queue.take();//tack底层也进行了加锁,不需要我们自己定义
                System.out.println("获取食物"+food);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<>(1);
        Customer customer = new Customer(queue);
        Cook cook = new Cook(queue);
        customer.setName("吃货");
        cook.setName("厨师");

        customer.start();
        cook.start();
    }
}
  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泰勒今天想展开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值