Reputation: 56
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.
Upvotes: 3
Views: 2099
Reputation: 111229
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<>())
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 Choosing the best concurrency list in Java
Upvotes: 4