
 桌子上有面条-》吃货执行
 桌子上没面条-》生产者制造执行
 
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();
    }
}
                


















