关于java实现生产者和消费者模型代码,输出消费者消费全为null是什么情况?

/**
 * 测试类
 */
public class Test {
    public static void main(String[] args) {
        // 创建缓冲区
        ProductStack productStack = new ProductStack();
        // 创建任务对象
        ProductRunnable productRunnable = new ProductRunnable(productStack);
        ConsumerRunnable consumerRunnable = new ConsumerRunnable(productStack);
        // 创建线程对象
        new Thread(productRunnable, "生产者").start();
        new Thread(consumerRunnable, "消费者").start();

    }
}

/**
 * 商品类
 */
class Product{
    private String name;
    private String color;

    public Product(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return color + "的" + name;
    }
}

/**
 * 缓冲区,用来放生产的商品
 * 以及生产商品的方法,消费商品的方法
 */
class ProductStack{
    private Product product;
    // 标记,有商品为true,没商品为false
    private boolean flag = false;



    /**
     * 提供一个生产方法
     * @param name
     * @param color
     */
    public synchronized void producter(String name, String color){
        // 当仓库中没商品时,生产商品,即flag=false时
        while (flag){ // 默认值为false,所以此处不执行,执行的时候flag一定是true
            // 当有商品时,需要等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 没商品时需要生产
        Product product = new Product(name, color);
        System.out.println(Thread.currentThread().getName() + "生产了" + product);
        // 休眠
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 生产完毕,此时工厂内有商品,更改flag状态
        this.flag = true;
        // 唤醒消费者,唤醒和等待都需要在一个同步方法中
        this.notify();
    }

    /**
     * 提供一个消费方法
     */
    public synchronized void consumer(){
        // 如果没有产品,则不消费,在线程池中等待
        while (!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 有产品则消费
        System.out.println(Thread.currentThread().getName() + "消费了" + this.product);
        // 休眠
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 更改标记
        this.flag = false;
        // 清空产品
        this.product = null;
        // 唤醒生产者
        this.notify();
    }

}

/**
 * 创建生产者的线程
 */
class ProductRunnable implements Runnable{
    private ProductStack productStack;
                        
    public ProductRunnable(ProductStack productStack) {
        this.productStack = productStack;
    }

    @Override
    public void run() {
        // 奇数生产馒头,偶数生产玉米棒
        int i = 0;
        while (true){
            if (i % 2 == 0){
                productStack.producter("馒头" + i, "白色的" );
            }else {
                productStack.producter("玉米棒" + i, "黄色的");
            }
            i++;
        }
    }
}

/**
 * 消费者线程
 */
class ConsumerRunnable implements Runnable{

    private ProductStack productStack;
    public ConsumerRunnable(ProductStack productStack) {
        this.productStack = productStack;
    }
    @Override
    public void run() {
        while (true){
            productStack.consumer();
        }
    }
}

输出结果是下面这样的:

生产者生产了白色的的馒头0
消费者消费了null
生产者生产了黄色的的玉米棒1
消费者消费了null
生产者生产了白色的的馒头2
消费者消费了null
生产者生产了黄色的的玉米棒3
消费者消费了null
生产者生产了白色的的馒头4
消费者消费了null

把79行代码

Product product = new Product(name, color);

改为

product = new Product(name, color);

这样才是使用成员变量。

找到问题了,79行属于是新定义了一个Product的局部变量,导致成员变量product永远为null,属实低级错误

您好,我是有问必答小助手,您的问题已经有小伙伴解答了,您看下是否解决,可以追评进行沟通哦~

如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~

ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632