Java生产者消费者问题详解

gghh######生产者消费者问题是操作系统中的经典问题,先用声明Thread子类的方法来实现

问题:

**顾客去包子店中买包子
包子每次只能生产一个只能消费一个
包子有天津狗不理和无锡灌汤包两类,价格分别是20元和10元。
蒸笼中没有包子,店家才能生产,否则等待。
蒸笼中有包子,顾客才能消费,否则等待。
请实现此过程**

图解.png

首先要设计类
  • 包子是生产者和消费者共有的,作为一类,包子的成员变量是其品牌,价格,存在状态,包子的存在状态需要更改,所以要有一个get和set方法
  • 生产者类:要有一个生产包子的方法,方法逻辑是有包子则等待,没包子才生产,生产完成了更改包子状态,通知消费者
  • 消费者类类:要有一个消费包子的方法,方法逻辑是有包子才消费,消费完成后更改包子状态,通知生产者继续生产包子
  • 一个测试类,创建包子对象,包子是共享数据,生产者消费者需要知道包子的具体状态,所以生产者消费者中需要有传入包子对象的构造方法

1. 先写包子类

/**
 * @author Joker
 */
public class BaoZi
{
    String name;
    int price;
    boolean flag = false;

//获取和设置包子的成员变量
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public int getPrice()
    {
        return price;
    }
    public void setPrice(int price)
    {
        this.price = price;
    }
    public boolean isFlag()
    {
        return flag;
    }
    public void setFlag(boolean flag)
    {
        this.flag = flag;
    }

    /**
     * 包子的有参构造方法,用于生产包子时创建相应品牌价格的包子对象
    */
    public BaoZi(String name, int price)
    {
        super();
        this.name = name;
        this.price = price;
    }

    /**
     * 包子的无参构造
     */
    public BaoZi()
    {
    }

      /**
      * 生产包子方法,用于生产者调用,同步线程声明synchronized 关键字
      * 包子有不同的品牌和价格,所以需要传入对应的成员变量值
      */
    public synchronized void produce(String name, int price)
    {
        if (flag)
        {
            try
            {
                wait();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }   

    //更改传递包子的属性 
        this.name = name;
        this.price = price; 

    //更改包子的状态并通知消费者
        flag = true;
        notify();
}

     /**
      * 消费包子方法,用于消费者调用,同步线程声明synchronized 关键字
      * 消费者只能消费生产者已经生产好的包子,所以无需更改包子的成员参数
      */
    public synchronized void consume()
    {
        if (!flag)
        {
            try
            {
                wait();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        //表明正在消费何种包子(必须是刚才生产者已经生产好的)
        System.out.println("正在消费" + getName() + ":" + getPrice() + "元");

          //更改包子存在状态并通知生产者继续生产
        flag = false;
        notify();
    }

}

2. 生产者类

public class Producer extends Thread
{
    BaoZi baoZi;
    /**
     * @param 构造方法接收包子对象进行通信
     */

    public Producer(BaoZi baoZi)
    {
        this.baoZi = baoZi;
    }

    @Override
    public void run()
    {
        super.run();
        // i计数来生产不同类型的包子,偶数次时生产天津狗不理
        int i = 0;
        while (true)
        {
            if (i % 2 == 0)
            {
                // 调用produce方法生产对应的包子并输出
                baoZi.produce("天津狗不理", 10);
                System.out.println("正在生产" + baoZi.getName() + ":" + baoZi.getPrice() + "元");
            }
            else
            {
                baoZi.produce("无锡灌汤包", 20);
                System.out.println("正在生产" + baoZi.getName() + ":" + baoZi.getPrice() + "元");
            }
            i++;
        }
    }
}

3. 消费者类

public class Consumer extends Thread
{
    BaoZi baoZi;
    /**
     * 构造方法 传入baozi对象进行通信
     */
    public Consumer(BaoZi baoZi2)
    {
        baoZi = baoZi2;
    }

    @Override
    public void run()
    {       
       super.run();
        while (true)
        {
            baoZi.consume();
        }
    }
}

4. 测试类

public class TestMain
{
    public static void main(String[] args)
    {
        Baozi baozi = new Baozi(null, 0);
        Producer producer = new Producer(baozi);
        Customer customer = new Customer(baozi);
               //启动线程
        producer.start();
        customer.start();
    }
}

5. 运行结果

控制台输出.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值