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

使用ArrayList.add()随机抛出ArrayIndexOutOfBoundsException问题求助

ArrayList无参add()抛出ArrayIndexOutOfBoundsException(索引-1)排查方案

核心原因

从异常堆栈和随机出现的现象来看,根本问题是线程不安全的ArrayList在多线程并发环境下被修改,导致内部状态损坏。

ArrayList本身不支持并发操作,当多个线程同时执行add、扩容等操作时,会破坏其内部的size、elementData数组等状态的一致性。比如:

  • 线程A正在执行扩容逻辑,修改了elementData数组的长度;
  • 线程B同时修改size变量,可能导致size被错误地更新为-1;
  • 后续执行add()时,基于损坏的size计算索引,就会抛出ArrayIndexOutOfBoundsException: Index -1 out of bounds异常。

代码疑点说明

你提供的代码片段中,_launchedRequestsMap是局部变量,不存在多线程共享问题,这段代码如果触发异常应该是NullPointerException(当requestLaunchType不存在时),和当前异常无关。实际问题出在TestRequestPoolSingleton.addToLaunched方法中维护的共享ArrayList实例。

解决方案

针对多线程环境下的集合操作,推荐以下几种修复方式:

  • 替换为线程安全集合:将共享的ArrayList替换为Collections.synchronizedList(new ArrayList<>()),或者CopyOnWriteArrayList(适合读多写少的场景,写操作会复制整个数组,性能开销较大)。
  • 手动加锁保护:在所有操作该共享ArrayList的代码块上添加synchronized锁,或者使用ReentrantLock保证同一时间只有一个线程修改集合状态。示例:
// 在TestRequestPoolSingleton中加锁
private final List<String> launchedRequests = new ArrayList<>();
private final Object lock = new Object();

public void addToLaunched(String requestId) {
    synchronized(lock) {
        launchedRequests.add(requestId);
    }
}
  • 检查单例类的线程安全:确认TestRequestPoolSingleton的实现是否存在线程不安全的初始化或访问逻辑,确保共享集合的所有操作都经过线程安全处理。

验证点

  • 确认TestRequestPoolSingleton中的ArrayList是否为多线程共享的单例实例;
  • 查看addToLaunched方法的实现,是否存在未加锁的并发修改操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 06:55:28