加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用for-each循环时LinkedList中的Nullpointer异常

发布时间:2020-12-14 16:30:55 所属栏目:Java 来源:网络整理
导读:我遇到了非常奇怪的 Java行为,我不知道它是不是一个bug,或者 我错过了什么. 代码只是通过stateStack(LinkedList)列表并销毁所有状态. public void clearStates(){ LogFactory.getLog(StateController.class.getName()) .info( "Clearing states. #ofstates="
我遇到了非常奇怪的 Java行为,我不知道它是不是一个bug,或者
我错过了什么.

代码只是通过stateStack(LinkedList)列表并销毁所有状态.

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)
    // ... //

这段代码通常没有问题,已经生产了一年多.

这可能是Java bug吗?

/ *更新* /

destroy()调用不会修改stateStack.如果我认为Java会
抛出ConcurrentModificationException.

stateStack填充了1个状态,它覆盖了destroy,但只是覆盖了
当地的修改.超级实现比打印额外的日志(“销毁状态……”),这不在日志文件中,所以我猜这个异常被抛出
迭代的开始.

public void destroy()
{
    destroyed = true;
    LogFactory.getLog(State.class.getName()).info( "Destorying state : "+getClass().getName());
    propertyChangeSupport.firePropertyChange(PROP_DESTROYED,null,this);
}

解决方法

下面的代码几乎每次运行时都会生成相同的异常 – 这个想法是在从另一个线程迭代时修改列表.使用(非)幸运时间,修改发生在checkForComodification之后但在next = next.next之前;在ListItr#next方法中,导致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();
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读