I have this code (Obfuscated) as part of a large application and it’s getting a NullPointerException on the object.doSomething() line. Since we just checked the isEmpty() call and there is no other thread polling this queue, how is this possible? There are other threads adding to the queue; is it possible concurrent adds permanently screwed up the queue?
I tried reading the source code of ArrayDeque and it uses head == tail as a check for isEmpty(). Is it possible some weird collision during adds made head != tail but the head point to null?
private final Queue<Task> active = new ArrayDeque<Task>();
if (!this.active.isEmpty()) {
SomeType object = null;
object = this.active.poll();
object.doSomething();
}
Even if there is no other thread polling, there are probably other threads pushing.
This means in a concurrent access that tail can be modified incorrectly, and if tail is corrupted you may never get to the point where
head == tail, hence theNullPointerException.As @dacwe stated, the documentation clearly specify that you (or the developers of this obfuscated application) should not use
ArrayDequein a concurrent environment, this is one of the possible problems with concurrency.If you want a threadsafe
Queueyou can useLinkedBlockingQueue, if you need aDequeueyou can useLinkedBlockingDeque.Resources: