I came across very odd Java behaviour, and I don\'t know if it is a bug, or am I missing something.
The code simply goes through the stateStack (LinkedList) list and
The piece of code below generates the same exception almost every time I run it - the idea is to modify the list while iterating from another thread. With (un-)lucky timing, the modification happens after checkForComodification
but before next = next.next;
in the ListItr#next
method, causing a NPE.
Exception in thread "main" java.lang.NullPointerException at java.util.LinkedList$ListItr.next(LinkedList.java:891) at javaapplication4.Test1.main(Test1.java:74)
public class Test {
public static void main(String[] args) {
final int SIZE = 100000;
final Random rand = new Random();
final List<Integer> list = new LinkedList<>();
for (int i = 0; i < SIZE; i++) {
list.add(i);
}
Runnable remove = new Runnable() {
@Override
public void run() {
while (true) {
int i = rand.nextInt(SIZE);
list.remove(i);
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
break;
}
list.add(i);
}
}
};
Thread t = new Thread(remove);
t.start();
for (int i = 0; i < 100; i++) {
try {
for (Integer j: list) {
///whatever
}
} catch (ConcurrentModificationException e) {
} catch (NullPointerException e) {
e.printStackTrace();
}
}
t.interrupt();
}
}
This is the internal implementation of LinkedList.ListItr.next()
:
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next; // your stacktrace says the NullPointerException happens here
nextIndex++;
return lastReturned.item;
}
The NullPointerException
happens because the internal variable next
is null
; however, it seems that hasNext()
is validating that there is a next element.
It seems to me that:
destroy()
while iterating over the list.If you update your answer with your implementation of destroy()
as sugested by @mthmulders, I either update, correct or delete my answer.