a_m_d_y_e_s
音乐电台
采纳率100%
2020-09-11 16:37

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

#生产者和消费者应当共用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条回答

  • weixin_43860574 半路出码 7月前

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

    点赞 1 评论 复制链接分享
  • weixin_43860574 半路出码 4月前

    chickens.length = 10的,当count =9的时候,其实chickens 已经满了。chickens[10]肯定越界了。数组下标是从0开始的。改成:if(count == chickens.length-1),才对。

    点赞 评论 复制链接分享