You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java大矩阵相加触发ArrayIndexOutOfBoundsException异常如何解决

问题根因

你遇到的ArrayIndexOutOfBounds异常核心是分块逻辑未适配奇数长度的矩阵边界,具体问题如下:

  • 当前你固定按N/2、M/2的步长拆分矩阵,Java整数除法会向下取整,当矩阵的行数N或列数M为奇数时,最后一次分块的边界会超出原矩阵的实际长宽,比如你示例中矩阵列数为7,M/2=3,最后一次分块的起始列d=6时,d+M/2=9远大于7,访问mat_A[i][j]时直接越界。
  • 同样场景下,最后一块的实际行数/列数不足N/2、M/2,循环中对submatrix[k][l]的访问也会超出子矩阵的索引范围。
  • 额外说明:你当前在thread.start()后直接调用thread.join(),多线程逻辑实际是串行执行的,没有发挥多线程的作用。

修复方案

方案1:适配动态块大小(推荐)

修改分块逻辑,每次计算当前块的实际高度和宽度,避免超出边界,同时调整线程等待逻辑发挥多线程作用,修改后的核心代码如下:

// 修改后的addmatrix方法
public static void addmatrix(int[][] mat_A,int[][] mat_B,int[][] submatrix1,int[][] submatrix2,int N,int M)throws Exception
{
    ThreadOperation m1;
    ThreadOperation.initialize(N,M);
    ArrayList<Thread> threads = new ArrayList<Thread>();
    int c=0,d;
    int blockHeight = N/2;
    int blockWidth = M/2;
    while(c<N)
    {
        // 计算当前块实际高度,避免超过总行数
        int actualHeight = Math.min(blockHeight, N - c);
        d=0;
        while(d<M)
        {
            // 计算当前块实际宽度,避免超过总列数
            int actualWidth = Math.min(blockWidth, M - d);
            int i=0,j=0,k,l;
            for(k=0,i=c; i < c + actualHeight; i++, k++)
            {
                for(l=0,j=d; j < d + actualWidth; j++, l++)
                {
                    submatrix1[k][l]=mat_A[i][j];
                    submatrix2[k][l]=mat_B[i][j];
                }
            }
            // ThreadOperation构造方法新增actualHeight、actualWidth参数,内部逻辑也适配实际尺寸访问
            m1=new ThreadOperation(mat_A,mat_B,submatrix1,submatrix2,N,M,c,d,actualHeight,actualWidth);
            Thread thread =new Thread(m1);
            thread.start();
            threads.add(thread);
            d=d+blockWidth;
        }
        c=c+blockHeight;
    }
    // 所有线程启动完成后统一等待执行结束
    for(Thread t : threads){
        t.join();
    }
}

// 修改后的devidematrix方法
public static void devidematrix(int[][] mat_A,int[][] submatrix,int N,int M)
{
    int c=0,d;
    int blockHeight = N/2;
    int blockWidth = M/2;
    while(c<N)
    {
        int actualHeight = Math.min(blockHeight, N - c);
        d=0;
        while(d<M)
        {
            int actualWidth = Math.min(blockWidth, M - d);
            int i=0,j=0,k,l;
            for( k=0,i=c;i < c + actualHeight;i++,k++)
            {
                for( l=0,j=d;j < d + actualWidth;j++,l++)
                {
                    submatrix[k][l]=mat_A[i][j];
                }
            }
            d=d+blockWidth;
        }
        c=c+blockHeight;
    }
}

方案2:矩阵补0对齐

如果不想修改原有分块逻辑,可以先对输入矩阵做补0处理,将行数、列数都补为最近的偶数,计算完成后再截取前N行M列的结果即可,实现更简单。

内容的提问来源于stack exchange,提问作者Dazzleman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 14:15:03