关于Java多线程生产者消费者实例

实例题目:

1.在一个KFC内,服务员负责生产食物,消费者负责消费食物;

2.当生产到一定数量可以休息一下,直到消费完食物,再马上生产,一直循环
程序涉及到的内容:

1.这设计到java模式思想:生产者消费者模式

2.要保证操作对象的统一性,即消费者和服务者都是跟同一个KFC发生关系的,KFC只能new一次

3.this.notifyAll();和 this.wait();一个是所有唤醒的意思,一个是让自己等待的意思;

比如本题中,生产者生产完毕后,先所有唤醒(包括消费者和生产者),再让所有自己(生产者)等待

这时,消费者开始消费,直到食材不够,先所有唤醒(包括消费者和生产者),再让所有自己(消费者)等待

一直执行上面的操作的循环

4.生产者和消费者都要继承Thread,才能实现多线程的启动

程序设计的步骤思路:

1.创建一个食物类Food,有存放/获取食物的名称的数量

2.创建一个KFC类,有生产食物和消费食物的方法

3.创建一个客户类Customer,继承Thread,重写run方法,在run方法里面进行消费食物操作

4.创建一个服务员类Produce,继承Thread,重写run方法,在run方法里面进行生产食物的操作

5.创建主方法的调用类

Food类

public class Food {

    public final static int max = 20;//大于最大食材数,生产者释放锁,处于等待状态
    public final static int min = 5;//小于最小食材数,消费者释放锁,处于等待状态
    public static int hamburger = 20;//初始食材数

}

KFC类

public class KFC {

    public void produce(int index, String name) {
        try {
            synchronized (this) {
    //notifyAll和wait需要在锁内,否则调用方法时会报获取对象异常
                this.notifyAll();
                    Food.hamburger = Food.hamburger + index;
                    System.out.println("食材补充了" + index + ",生产者为" + name+ ",剩余总量为" + Food.hamburger);

                if (Food.hamburger >= Food.max) {
                    System.out.println("食材剩余总量充足,暂停生产");
                    // 使用wait时,需要保证此线程正在使用
                    this.wait(100);
                }
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void custom(int index, String name) {
        try {
            synchronized (this) {
            //唤醒所有线程,允许获取锁
                this.notifyAll();

                    Food.hamburger = Food.hamburger - index;
                    System.out.println("食材消耗了" + index + ",消费者为" + name+ ",剩余总量为" + Food.hamburger);

                if (Food.hamburger <= Food.min) {
                    System.out.println("食材剩余不足,请及时生产生产");

                //释放当前线程锁,并休眠
                    this.wait(100);
                }
            }

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

Customer类

public class Customer extends Thread {

    public KFC kfc;
    public String name;

    public  Customer(KFC kfc,String name){
        this.kfc=kfc;
        this.name=name;
    }

    public void run(){
    //食材数大于最小食材数时可以进行消费
        while (Food.hamburger > Food.min) {
        kfc.custom(3, name);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    }


}

Produce类

public class Produce extends Thread {

    public KFC kfc;
    public String name;

    public  Produce(KFC kfc,String name){
        this.kfc=kfc;
        this.name=name;
    }

    public void run(){
    //当食材数小于最大食材数时,就可以进行生产
        while (Food.hamburger < Food.max) {
        kfc.produce(5, name);
        try {
        //此线程休眠1秒,否则会造成都是同一个人生产的结果
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    }

}

主函数调用类

public class Main {
    //生产者消费者例子
    public static void main(String[] arg0){

    // 只实例化一个KFC对象,保证每一个服务员和用户在同一个KFC对象内
    KFC kfc = new KFC();

    //实例化2个客户对象
    Customer c1 = new Customer(kfc,"客户A");
    Customer c2 = new Customer(kfc,"客户B");


    //实例化2个服务员对象
    Produce waiter1 = new Produce(kfc,"生产者A");
    Produce waiter2 = new Produce(kfc,"生产者B");


    //让所有的对象的线程都开始工作
    waiter1.start();
    waiter2.start();

    c1.start();
    c2.start();
  }
}

最终效果

这里写图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值