【问题标题】:ArrayIndexOutOfBoundsException while converting linkedList to array list将linkedList转换为数组列表时出现ArrayIndexOutOfBoundsException
【发布时间】:2014-01-06 06:07:19
【问题描述】:

我正在尝试将linkedList 转换为ArrayList,如下所示。

private LinkedList<myData> myLinkedList= new LinkedList<myData>();  
public Collection<myData> getData()  
 {
  return new ArrayList<myData>(myLinkedList);  
 }

linkedList 可能被多个线程更新。在生产中进行测试时,出现以下错误。错误不一致。所以我知道它可能是一周一次,一个月左右。

java.lang.ArrayIndexOutOfBoundsException: 15   
at java.util.LinkedList.toArray(LinkedList.java:866)   
at java.util.ArrayList.<init>(ArrayList.java:131)   
at org.xxx.yyy.zzz.getData(Data.java:291)  

有什么方法可以与linkedList的并发修改有关。感谢您对此的任何帮助。

【问题讨论】:

  • 是的。您可能应该在您的实例上进行同步。或者使用快速失败的版本。
  • 如果你有多个线程修改LinkedList ...是的。当它去复制它分配一个数组,然后遍历列表。显然,您在创建数组后向列表中添加了一个元素,而数组现在太小了。

标签: java arraylist linked-list


【解决方案1】:

toArray 失败只是一个你做了一些根本危险的事情的症状。

来自documentation of LinkedList

如果多个线程同时访问一个链表,并且至少有一个线程在结构上修改了链表,则它必须在外部同步。

您要么需要添加同步(不仅仅是toArray,而且基本上是列表的所有用途)或使用设计为线程安全的并发集合之一。

【讨论】:

    【解决方案2】:

    LinkedList#toArray() 就是这样实现的(Oracle JDK 7)

    public Object[] toArray() {
        Object[] result = new Object[size];
        int i = 0;
        for (Node<E> x = first; x != null; x = x.next)
            result[i++] = x.item;
        return result;
    }
    

    如果您在构造result 数组之后但在for 循环之前添加到LinkedList,则for 循环内的数组访问表达式将在尝试访问索引时导致ArrayIndexOutOfBoundsException大于原来的size

    您确实应该设置一些同步障碍,以免发生这种情况。

    【讨论】:

      猜你喜欢
      • 2014-11-25
      • 2015-02-04
      • 2018-05-09
      • 2014-08-12
      • 1970-01-01
      • 2022-01-18
      • 2023-03-06
      • 2020-03-09
      • 1970-01-01
      相关资源
      最近更新 更多