【问题标题】:How to fix Fatal Exception: java.lang.IndexOutOfBoundsException Index: 0, Size: 1如何修复致命异常:java.lang.IndexOutOfBoundsException 索引:0,大小:1
【发布时间】:2020-11-29 22:35:45
【问题描述】:

Kotlin 程序 sn-p:

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,第一个(现有)元素也可以通过 index=0 引用。

据我所知,它应该可以工作。但有时不会。

【问题讨论】:

  • 似乎更像是 kotlin 问题而不是 java 问题
  • 可以多线程访问列表吗?
  • 是的,更多线程(kotlin 调度程序)可以访问列表

标签: java android multithreading kotlin arraylist


【解决方案1】:

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

一种可能的解决方法是使两个线程无法同时调用列表的方法(“互斥”)。这很容易通过 Collections.synchronizedList 实现

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

如果您从列表中读取的元素多于写入的内容,则另一种方法是使用 CopyOnWriteArrayList 而不是 ArrayList

我看到您正在使用来自名为 queue 的类中的代码。在这种情况下,您可能希望使用实际的队列数据结构而不是列表,并且标准库有许多选项可供您选择,具体取决于您想要的行为。请参阅此问题,例如 Choosing the best concurrency list in Java

【讨论】:

  • 感谢您清晰的解释和建议。我想,Collections.synchronizedList 会是我的朋友。
猜你喜欢
  • 2021-07-12
  • 2016-12-28
  • 2013-07-29
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
  • 2016-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多