使用for-each循环时LinkedList中的Nullpointer异常 [英] Nullpointer exception in LinkedList while using for-each loop

查看:88
本文介绍了使用for-each循环时LinkedList中的Nullpointer异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了非常奇怪的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆