Nullpointer exception in LinkedList while using for-each loop

后端 未结 2 1648
攒了一身酷
攒了一身酷 2021-01-18 06:20

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

相关标签:
2条回答
  • 2021-01-18 06:53

    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();
        }
    }
    
    0 讨论(0)
  • 2021-01-18 07:04

    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:

    • you have more than one thread modifying your list, OR
    • you are modifying your list in the implementation of 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.

    0 讨论(0)
提交回复
热议问题