两个线程通讯(生产-卖面包问题)

多线程通讯题目:

昨天看了一家公司的笔试题,问题生产、销售面包问题,题目是这样的:生产者销售面包,但是因为疫情原因,只能一个一个的生产,生产好之后在通知消费者买,题目大意是这样的。其实这就是一道多线程通讯问题,代码如下所示:

package com.springboot.study.tests.threads.salebread;

/**
 * @Author: guodong
 * @Date: 2021/7/1 16:35
 * @Version: 1.0
 * @Description:
 */
public class TestBread {

    public static void main(String[] args) {
        Store store=new Store();
        Maker m = new Maker(store);
        Saler s1 = new Saler(store);
        m.start();
        s1.start();
    }

}


/**
 * 面包店类
 */
class Store{

    /**
     * 面包的个数
     */
    volatile int num = 0;

    /**
     * 面包的计数
     */
    volatile int count = 0;

    /**
     * 生产面包
     */
    public synchronized void make(){
        if(num == 0){
            count = count + 1;
            num = num + 1;
            System.out.println("生产者:当前面包是第:"+ count +"个");
        }

        /**
         *  通知消费者来卖面包,自己阻塞
         */
        this.notify();
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 销售面包
     */
    public synchronized void sale(){
        if(num > 0){
            System.out.println("消费者:当前面包是第:" + count + "个");
            num = 0;
        }else{
            /**
             * 通知生产者生产面包
             * 在这个程序里与notify()相同
             */
            this.notifyAll();
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

/**
 * 生产者线程
 */
class Maker extends Thread{

    Store s;

    public Maker(Store s) {
        this.s = s;
    }

    @Override
    public void run(){
        while(true){
            s.make();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 消费者线程
 */
class Saler extends Thread{

    Store s;

    public Saler(Store s) {
        this.s = s;
    }

    @Override
    public void run(){
        while(true){
            s.sale();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

解析如下:面包个数是一个一个来的,计数和面包个数都是使用volatile这个关键字来的,这个关键字保证变量是内存可见性的。运行结果如下所示:

生产者:当前面包是第:1个
消费者:当前面包是第:1个
生产者:当前面包是第:2个
消费者:当前面包是第:2个
生产者:当前面包是第:3个
消费者:当前面包是第:3个
生产者:当前面包是第:4个
消费者:当前面包是第:4个
生产者:当前面包是第:5个
消费者:当前面包是第:5个
生产者:当前面包是第:6个
消费者:当前面包是第:6个
郭慕荣博客园
原文地址:https://www.cnblogs.com/jelly12345/p/14960101.html