【问题标题】:Java-Threads ArrayIndexOutOfBoundsException [duplicate]Java线程ArrayIndexOutOfBoundsException [重复]
【发布时间】:2014-08-31 13:23:14
【问题描述】:

我用线程编写了一个程序(用于自学目的),它使用 2 个线程计算数组元素的乘法。但是我为这两个线程都得到了一个 ArrayIndexOutOfBoundsException。错误如下所示:

Exception in thread "Thread-1" Exception in thread "Thread-0" Executing multiplying of last2elements
          java.lang.ArrayIndexOutOfBoundsException: 1
          at FirstPart.run(FirstPart.java:12)
          java.lang.ArrayIndexOutOfBoundsException: 1
          at SecondPart.run(SecondPart.java:10)

Java 代码:

FirstPart.java

public class FirstPart extends Thread {
    int multiply = 1;
    static int n;
    static int[] v = new int[n];

    public void run() {
        System.out.println("Executing multiplying of first "+MultiplyDemo.cap1+"elements"); 
        for(int i = 1; i <= MultiplyDemo.cap1; i++) {
            multiply = multiply * FirstPart.v[i];
            System.out.println("Multiplication is "+ multiply);
        }

    }
}

SecondPart.java:

public class SecondPart extends Thread {
    int multiply = 1;

    public void run() {
        System.out.println("Executing multiplying of last " + (FirstPart.n - MultiplyDemo.cap1) + "elements"); 

        for(int i = MultiplyDemo.cap1;i <= FirstPart.n; i++) {
            multiply=multiply*FirstPart.v[i];
            System.out.println("Multiplication is "+multiply);
        }
    }
}

MultiplyDemo.java:

import java.util.Scanner;
import java.util.Vector;


public class MultiplyDemo {

    public static int cap1;


    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.println("introduceti numarul de elemente din vector:");
        FirstPart.n=s.nextInt();

        int []v=new int[FirstPart.n];
        System.out.println("Elementele vectorului sunt");
        for(int i = 0; i < v.length; i++)
            v[i]=s.nextInt();         
        cap1=FirstPart.n / 2;

        FirstPart thread1=new FirstPart();
        SecondPart thread2=new SecondPart();

        thread1.start();
        thread2.start();

        try { // wait for completion of all thread and then sum
            thread1.join();
            thread2.join(); //wait for completion of MathCos object 
            double z = thread1.multiply + thread2.multiply;
            System.out.println("produsul elementelor este" +z);
        } 
        catch(InterruptedException IntExp) {
        }

    }
}

【问题讨论】:

    标签: java arrays multithreading exception indexoutofboundsexception


    【解决方案1】:

    数组索引是从 0 开始的;如果数组的大小为n,则有效索引在0..n-1 范围内。
    您所有的for 循环都使用&lt;= 进行检查,而不是使用&lt;,这就是您得到ArrayIndexOutOfBoundsException 的原因。

    通常,数组上的“for 循环”具有这种形式:

    Object[] array = new Object[size];
    for(int i = 0;i < array.length;i++) {
      ..
    }
    

    这样你永远不会超过数组的大小

    【讨论】:

    • 我明白我做错了什么,但你能告诉我我应该怎么做吗?这对我来说意味着整个世界!
    • i &lt;= FirstPart.n 替换为i &lt; FirstPart.v.length,将i &lt;= MultiplyDemo.cap1 替换为i &lt; FirstPart.v.length,这样就不会再出现异常了。
    • 只是一个问题:您是否在自学线程并且您在编写数组索引循环时遇到了麻烦?我认为您应该重新考虑您的学习计划步骤...
    【解决方案2】:

    让你的两个 for 循环到这个:

    for(int i=0; i < MultiplyDemo.cap1; i++)
    

    还有 PS:请以适当的格式发布问题,以便有人可以轻松提供帮助。

    【讨论】:

    • 但它不会做应该做的事情,SecondPart 类应该继续从 MultyplyDemo.cap1 乘以直到结束(数组的后半部分)
    【解决方案3】:

    MultiplyDemo.cap1 比你大 n 导致你的 for 循环试图访问一个不存在的索引:

    for(int i=1;i<=MultiplyDemo.cap1;i++)
        multiply=multiply*FirstPart.v[i]; // Misses index 0 and tries to go to index n, when n-1 is max
    

    【讨论】:

      【解决方案4】:

      FirstPart.v 仍然是一个空数组。您正在从 main() 方法将值分配给 n 并将值初始化为不影响 FirstPart.v

      的本地数组

      【讨论】:

      • 但我不知道如何更改代码,如果我将 n,v, 声明移到我的 main 我无法访问它们,我会收到错误。我是初学者,所以不知道这种情况该怎么办。
      【解决方案5】:

      您的“n”默认为 0,因此您的 v 数组的长度为 0。

      这就是索引超出范围的原因。

      在您的 main 方法中,您正在初始化一个新的“v”变量。请记住,这个“v”数组与“FirstPart”中的静态“v”数组不同

      【讨论】:

      • 不,在 decleration 中 v 数组被初始化,而 n 为 0。在 main 中,不同的实例(也称为 v)被初始化。
      • 对不起,我的意思是 n 已在 main 中初始化
      • 仍然,不正确。 main 初始化一个不同的实例,与 FirstPart.v 无关,该实例在 main 执行任何操作之前在 decleration 中初始化。
      • 根据上面的代码在 Main FirstPart.n=s.nextInt(); n 是一个静态变量 - 它怎么可能是一个不同的实例?
      • n 在 main 中初始化 AFTER v 已经初始化,所以在 main 中初始化 n 不会影响任何事情。
      猜你喜欢
      • 2016-08-31
      • 2011-02-25
      • 2018-08-25
      • 1970-01-01
      • 2011-03-30
      • 2011-03-22
      • 1970-01-01
      • 2015-11-08
      • 2014-11-17
      相关资源
      最近更新 更多