天天喝怡宝 2021-05-21 19:48 采纳率: 0%
浏览 32

关于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

  • 写回答

3条回答 默认 最新

  • 关注

    把79行代码

    Product product = new Product(name, color);

    改为

    product = new Product(name, color);

    这样才是使用成员变量。

    评论

报告相同问题?

悬赏问题

  • ¥15 石墨烯磁表面等离子体
  • ¥15 angular 项目无法启动
  • ¥15 安装wampserver,图标绿色,但是无法进入软件
  • ¥15 C++ MFC 标准库 加密解密解惑
  • ¥15 两条数据合并成一条数据
  • ¥15 Ubuntu虚拟机设置
  • ¥15 comsol三维模型中磁场为什么没有“速度(洛伦兹项)”这一选项
  • ¥15 electron 如何实现自定义安装界面
  • ¥15 关于#linux#的问题:子进程C运行“ls –l”命令,且显示“C运行ls-l命令”(语言-c语言)
  • ¥15 vs code配置c语言遇到这个问题