如何修复致命异常:java.lang.IndexOutOfBoundsException 索引:0,大小:1

huangapple go评论85阅读模式
英文:

How to fix Fatal Exception: java.lang.IndexOutOfBoundsException Index: 0, Size: 1

问题

Kotlin程序片段:

fun peek() = if (!elements.isEmpty() && elements.size > 0) elements[0] else null

它运行得很好,但有时我会收到Firebase的崩溃报告:

> 严重异常:java.lang.IndexOutOfBoundsException 索引:0,大小:1
> java.util.ArrayList.get (ArrayList.java:437)
> bigmick.ghu.util.Queue.peek (Queue.kt:17)

对我来说,这听起来很疯狂:列表的大小是1,而且第一个(存在的)元素可以通过索引=0引用。

据我所知,它应该能工作。但有时候却不行。
英文:

Kotlin program snippet:

fun peek() = if (!elements.isEmpty() && elements.size > 0) elements[0] else null

It works great, but sometimes I get a firebase crash report:

> Fatal Exception: java.lang.IndexOutOfBoundsException Index: 0, Size: 1
> java.util.ArrayList.get (ArrayList.java:437)
> bigmick.ghu.util.Queue.peek (Queue.kt:17)

For me it sounds crazy: the list's size is 1, also the first (existing) element can be referred by index=0.

As far as I know it should work. But sometimes it does not.

答案1

得分: 4

ArrayList类不是线程安全的。当一个线程在另一个线程调用您的方法的同时进行更改时,可能会发生意外和看似不可能的事情。

一个可能的修复方法是使两个线程不可能同时调用列表的方法("互斥")。这可以通过Collections.synchronizedList轻松实现。

elements = Collections.synchronizedList(new ArrayList<>())

如果您从列表中读取元素的频率远高于写入的频率,另一种选择是使用CopyOnWriteArrayList而不是ArrayList。

我看到您正在从一个名为queue的类中使用这段代码。在这种情况下,您可能希望使用实际的队列数据结构,而不是列表,标准库有许多选项供您选择,具体取决于您需要的行为。可以参考这个问题,例如:https://stackoverflow.com/questions/8203864/choosing-the-best-concurrency-list-in-java

英文:

The ArrayList class is not thread safe. When a thread makes a change at the same time another thread calls your method, unexpected and seemingly impossible things can happen.

A possible fix is to make it impossible for two threads to call methods of the list at the same time ("mutual exclusion"). This is easily achieved with Collections.synchronizedList

elements = Collections.synchronizedList(new ArrayList&lt;&gt;())

If you read elements from the list a lot more than you write, an alternative is to use CopyOnWriteArrayList instead of ArrayList

I see that you're using this code from a class called queue. In that case you may want to use an actual queue data structure instead of a list, and the standard library has many options you can choose from, depending on what behavior you want. See this question for example https://stackoverflow.com/questions/8203864/choosing-the-best-concurrency-list-in-java

huangapple
  • 本文由 发表于 2020年8月10日 18:15:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63338223.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定