Java 生产者和消费者模式练习 (2024.8.12)

        ProducerAndConsumerExercise1

package ProducerAndConsumer20240812;

public class ProducerAndConsumerExercise1 {
    public static void main(String[] args) {
        // 生产者(Producer)和消费者(Consumer)模式
        // 这是一个十分经典的多线程协作模式,其主要包含了两类线程

        // 1.生产者线程:用于生产数据(提供给消费者数据)
        // 2.消费者线程:用于消费数据(使用生产者的数据)

        // 实现生产者和消费者的关系,通常采用共享的数据区域;生产者将数据直接放置于共享数据区中,无需关心消费者的行为
        //                                              而消费者若需要则直接去共享数据区获取数据,无需关系生产者的行为

        // Object类中的等待和唤醒方法
        // void wait() 使当前线程进入等待,知道另一个线程调用该对象的notify()方法或notifyAll()方法
        // void notify() 唤醒正在等待对象监视器的单个线程
        // void notifyAll() 唤醒正在等待对象监视器的全部线程
    }
}

        ProducerAndConsumerExercise2

package ProducerAndConsumer20240812;

public class ProducerAndConsumerExercise2 {
    public static void main(String[] args) {
        /* 案例需求:
           桌子类(Desk):定义表示汉堡包数量的变量,定义锁对象变量,定义标记桌子上有无汉堡包的变量
           生产者类(Cooker):实现Runnable接口,重写run()方法,设置线程任务:
           1.判断是否有汉堡包,决定当前线程是否执行
           2.如果有汉堡包,就进入等待状态,如果没有汉堡包,继续执行,生产汉堡包
           3.生产汉堡包之后,更新桌子上汉堡包状态,唤醒消费者消费汉堡包
           消费者类(Foodie):实现Runnable接口,重写run()方法,设置线程任务:
           1.判断是否有汉堡包,决定当前线程是否执行
           2.如果没有汉堡包,就进入等待状态,如果有汉堡包,就消费汉堡包
           3.消费汉堡包后,更新桌子上汉堡包状态,唤醒生产者生产汉堡包
           测试类(Demo):里面有main方法,main方法中的代码步骤如下:
           创建生产者线程和消费者线程对象
           分别开启两个线程
        */

        Cook cook = new Cook();
        Foodie foodie = new Foodie();

        Thread thread1 = new Thread(cook, "厨师");
        Thread thread2 = new Thread(foodie, "顾客");

        thread1.start();
        thread2.start();
    }
}

        Cook

package ProducerAndConsumer20240812;

public class Cook implements Runnable{
    @Override
    public void run() {
        while (true) {
            synchronized (Desk.lock) {
                if (Desk.makeCount == 10) {
                    break;
                } else {
                    if (Desk.flag) {
                        // 此时表示有汉堡
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        // 此时表示没有汉堡包了
                        Desk.makeCount++;
                        System.out.println(Thread.currentThread().getName() +  "正在生产第" + Desk.makeCount +"汉堡包");
                        Desk.count++;
                        System.out.println("桌子上现在有" + Desk.count + "个汉堡包");
                        if (Desk.count > 0) {
                            Desk.flag = true;
                        }
                        Desk.lock.notifyAll();
                    }
                }
            }
        }
    }
}

        Foodie

package ProducerAndConsumer20240812;

public class Foodie implements Runnable {
    @Override
    public void run() {
        while (true) {
            synchronized (Desk.lock) {
                if (Desk.eatCount == 10) {
                    break;
                } else {
                    if (Desk.flag) {
                        // 此时是有汉堡的,顾客可以开始吃
                        Desk.eatCount++;
                        System.out.println(Thread.currentThread().getName() +  "正在吃第" + Desk.eatCount +"汉堡包");
                        Desk.count--;
                        System.out.println("桌子上现在有" + Desk.count + "个汉堡包");
                        if (Desk.count == 0) {
                            Desk.flag = false;
                        }
                        Desk.lock.notifyAll();
                    } else {
                        // 此时是没有汉堡的,顾客进入等待
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

        Desk

package ProducerAndConsumer20240812;

public class Desk {
    public static int eatCount = 0;
    public static int makeCount = 0;
    public static int count = 0;
    public static final Object lock = new Object();
    public static boolean flag = false;
}

         ProducerAndConsumerExercise3

package ProducerAndConsumer20240812;

public class ProducerAndConsumerExercise3 {
    public static void main(String[] args) {
        // 需求:
        /* 将Desk类中的变量,采用面向对象的方式封装起来
           生产者和消费者类中构造方法接收Desk类对象,之后在run方法中进行使用
           创建生产者和消费者线程对象,构造方法中传入Desk类对象
           开启两个线程
           */

        DeskPro deskPro = new DeskPro();

        CookPro cookPro = new CookPro(deskPro);
        FoodiePro foodiePro = new FoodiePro(deskPro);

        Thread thread1 = new Thread(cookPro, "厨师");
        Thread thread2 = new Thread(foodiePro, "顾客");

        thread1.start();
        thread2.start();

    }
}

        CookPro

package ProducerAndConsumer20240812;

public class CookPro implements Runnable {
    private DeskPro desk;

    public CookPro(DeskPro desk) {
        this.desk = desk;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (desk.getLock()) {
                if (desk.getMakeCount() == 10) {
                    break;
                } else {
                    if (desk.isFlag()) {
                        // 此时桌子上面有汉堡包,厨师等待
                        try {
                            desk.getLock().wait();
                        } catch (InterruptedException e){
                            e.printStackTrace();
                        }
                    } else {
                        // 此时桌子上面没有汉堡包,厨师开始做汉堡
                        int makeCount = desk.getMakeCount();
                        desk.setMakeCount(++makeCount);
                        System.out.println(Thread.currentThread().getName() + "正在做第" + desk.getMakeCount() + "个汉堡包");
                        int count = desk.getCount();
                        desk.setCount(++count);
                        if (desk.getCount() > 0) {
                            desk.setFlag(true);
                        }
                        // 叫醒顾客来吃汉堡
                        desk.getLock().notifyAll();
                    }
                }
            }
        }
    }
}

        FoodiePro

package ProducerAndConsumer20240812;

public class FoodiePro implements Runnable {
    private DeskPro desk;

    public FoodiePro (DeskPro desk) {
        this.desk = desk;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (desk.getLock()) {
                if (desk.getEatCount() == 10) {
                    // 吃了10个吃饱了
                    break;
                } else {
                    if (desk.isFlag()) {
                        // 此时桌子上有汉堡,顾客开始吃汉堡
                        int eatCount = desk.getEatCount();
                        desk.setEatCount(++eatCount);
                        System.out.println(Thread.currentThread().getName() + "正在吃第" + desk.getEatCount() + "个汉堡");
                        int count = desk.getCount();
                        desk.setCount(--count);
                        if (desk.getCount() == 0) {
                            desk.setFlag(false);
                        }
                        // 叫醒厨师来做汉堡
                        desk.getLock().notifyAll();
                    } else {
                        // 此时桌子上没有汉堡,顾客等待厨师做汉堡
                        try {
                            desk.getLock().wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

        DeskPro

package ProducerAndConsumer20240812;

public class DeskPro {
    private boolean flag;
    private int makeCount;
    private int eatCount;
    private int count;
    private final Object lock = new Object();

    public DeskPro() {
        this(false, 0, 0, 0);
    }

    public DeskPro(boolean flag, int makeCount, int eatCount, int count) {
        this.flag = flag;
        this.makeCount = makeCount;
        this.eatCount = eatCount;
        this.count = count;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public int getMakeCount() {
        return makeCount;
    }

    public void setMakeCount(int makeCount) {
        this.makeCount = makeCount;
    }

    public int getEatCount() {
        return eatCount;
    }

    public void setEatCount(int eatCount) {
        this.eatCount = eatCount;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public Object getLock() {
        return lock;
    }
}

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值