使用for-each循环时LinkedList中的Nullpointer异常 [英] Nullpointer exception in LinkedList while using for-each loop
问题描述
我遇到了非常奇怪的Java行为,并且我不知道这是否是错误,或者我错过了什么吗?
I came across very odd Java behaviour, and I don't know if it is a bug, or am I missing something.
代码只需遍历stateStack(LinkedList)列表并销毁所有状态.
The code simply goes through the stateStack (LinkedList) list and destroy all the states.
public void clearStates()
{
LogFactory.getLog(StateController.class.getName())
.info( "Clearing states. #ofstates="+stateStack.size());
for (State state : stateStack) // Line 132 (see exception)
{
state.destroy();
}
// ...
}
引发了以下异常:
INFO controllers.StateController : Clearing states. #ofstates=1
java.lang.NullPointerException\
at java.util.LinkedList$ListItr.next(LinkedList.java:891)
at *.controllers.StateController.clearStates(StateController.java:132)
// ... //
此代码通常可以正常工作,并且已经投入生产超过一年了.
This code usually works without a problem and has been in the production for more than a year.
这可能是Java错误吗?
Is it possible that this is Java bug?
/ *更新* /
destroy()调用不会修改stateStack.如果可以,我想Java会抛出ConcurrentModificationException.
destroy() call does not modify stateStack. If it would I guess Java would throw ConcurrentModificationException.
stateStack填充了1个状态,该状态覆盖destroy,但仅本地修改.然后,超级实现将打印其他日志(销毁状态..."),该日志不在日志文件中,因此我猜该异常抛出于迭代的开始.
stateStack was populated with 1 state, which overrides destroy, but only does local modifications. The super implementation than prints additional log ("Destroying state..."), which was not in the log file, so I guess the exception was thrown at the beginning of iteration.
public void destroy()
{
destroyed = true;
LogFactory.getLog(State.class.getName()).info( "Destorying state : "+getClass().getName());
propertyChangeSupport.firePropertyChange(PROP_DESTROYED, null, this);
}
推荐答案
几乎我每次运行以下代码段时,都会生成相同的异常-这个想法是在从另一个线程迭代时修改列表.幸运的是,修改发生在 checkForComodification
之后,但在 ListItr#next
方法中的 next = next.next;
之前,NPE.
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.
线程主"中的异常java.lang.NullPointerException在java.util.LinkedList $ ListItr.next(LinkedList.java:891)在javaapplication4.Test1.main(Test1.java:74)
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();
}
}
这篇关于使用for-each循环时LinkedList中的Nullpointer异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!