线程——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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,654评论 18 139
  • 题图 两个线程一个生产者个一个消费者 需求情景 涉及问题 代码实现(共三个类和一个main方法的测试类) 多个线程...
    极乐君阅读 504评论 0 4
  • 【 线程间的通讯 wait()在对象上等待,等待通知(在等待过程中释放对象锁、等待必须在同步块内、这个对象就是同步...
    征程_Journey阅读 701评论 0 0
  • 逃一节自习,出去逛逛 天地间什么都没有,只有我 和这伞下的世界 小雨淅沥,打在伞上沙沙 静静的走,走着鬼魅的步伐 ...
    林白驹阅读 253评论 0 0
  • 白衬衫,黑碎发,当年你倚墙浅笑,踏乱我整个年华。 苏倚楠以为自己的青春就这么在考卷、动漫中荒废了,但凡事无绝对,就...
    是青祁吖阅读 309评论 0 2