音乐电台 2020-09-11 16:37 采纳率: 100%
浏览 98
已采纳

萌新求问,大佬们看下这个为什么会偶尔出现数组越界的情况?

#生产者和消费者应当共用container的count,但是会偶尔出现数组下标越界和count不匹配

import java.awt.*;

public class Part6_TestProducerConsumer_1 {
    public static void main(String[] args) {
        //生产者和消费者必须共用一个容器
        SynContainer container = new SynContainer();
        Producer producer = new Producer(container);
        Consumer consumer = new Consumer(container);
        new Thread(producer,"生产者").start();
        new Thread(consumer, "消费者").start();
    }
}

class Chicken{
    int id;//鸡的序列号
    public Chicken(int id) {
        this.id = id;
    }
}

class Producer implements Runnable{
    SynContainer container;

    public Producer(SynContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 1; i < 100; i++) {
            try {
                container.putIn(new Chicken(i));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("生产者生产了第" + i + "只鸡," + "仓库中还有" + container.count + "只鸡");
        }
    }
}

class Consumer implements Runnable{
    SynContainer container;

    public Consumer(SynContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 1; i < 100; i++) {
            try {
                container.takeOut();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("消费者消费了第" + i + "只鸡," + "仓库中还有" + container.count + "只鸡");
        }
    }
}

class SynContainer{
    Chicken[] chickens = new Chicken[10];//定义容器中可以装鸡的数量
    int count = 0;//记录目前容器持有数量

    public synchronized void putIn(Chicken chicken) throws InterruptedException {
        //如果容器已满,停止生产,等待消费
        if(count == chickens.length){
            this.wait();
        }
        //如果容器不满
        chickens[count] = chicken;
        count ++;
        //通知消费者消费
        this.notifyAll();
    }

    public synchronized Chicken takeOut() throws InterruptedException {
        //如果容器为空,停止消费,等待生产
        if(count == 0){
            this.wait();
        }
        //如果容器不为空
        Chicken getChicken = chickens[count];
        count --;
        //通知生产者生产
        this.notifyAll();
        return getChicken;
    }
}
  • 写回答

2条回答 默认 最新

  • 半路出码 2020-09-11 17:28
    关注

    count ++;count --; 都不是原子操作的。换成AtomicInteger

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 请问读取环境变量文件失败是什么原因?
  • ¥15 在若依框架下实现人脸识别
  • ¥15 网络科学导论,网络控制
  • ¥100 安卓tv程序连接SQLSERVER2008问题
  • ¥15 利用Sentinel-2和Landsat8做一个水库的长时序NDVI的对比,为什么Snetinel-2计算的结果最小值特别小,而Lansat8就很平均
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载