2013-08-05 12 views
5

के लिए उपयोग करते समय लिंक्डलिस्ट में नलपोइंटर अपवाद मैं बहुत अजीब जावा व्यवहार में आया, और मुझे नहीं पता कि यह एक बग है, या क्या मुझे कुछ याद आ रहा है।प्रत्येक लूप

कोड बस स्टेटस्टैक (लिंक्डलिस्ट) सूची के माध्यम से जाता है और सभी राज्यों को नष्ट कर देता है।

public void clearStates() 
{ 
    LogFactory.getLog(StateController.class.getName()) 
     .info("Clearing states. #ofstates="+stateStack.size()); 
    for (State state : stateStack) // Line 132 (see exception) 
    { 
     state.destroy(); 
    } 

    // ... 
} 

निम्न अपवाद trowed गया था:

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

इस कोड को आमतौर पर एक समस्या के बिना काम करता है और एक वर्ष से अधिक के लिए उत्पादन में किया गया है।

क्या यह संभव है कि यह जावा बग है?

/* अद्यतन */

नष्ट() कॉल stateStack संशोधित नहीं करता है। अगर मुझे लगता है कि जावा को ConcurrentModificationException फेंक देगा।

स्टेटस्टैक 1 राज्य के साथ पॉप्युलेट किया गया था, जो नष्ट हो जाता है, लेकिन केवल स्थानीय संशोधन करता है। अतिरिक्त लॉग प्रिंट ("राज्य को नष्ट कर रहा है ...") से सुपर कार्यान्वयन, जो कि लॉग फ़ाइल में नहीं था, इसलिए मुझे लगता है कि अपवाद को पर पुनरावृत्ति की शुरुआत में फेंक दिया गया था।

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

लाइन '132' कहां है? शायद आपकी सूची में 'स्थिति' 'शून्य 'है? – Manuel

+0

आप स्टेटस्टैक कैसे और कहां प्राप्त करते हैं? – arjacsoh

+3

'state.destroy()' का कार्यान्वयन क्या है। यह क्या करता है? साथ ही, 'स्टेटस्टैक' कैसे आबादी है? – mthmulders

उत्तर

6

नीचे दिए गए कोड का टुकड़ा लगभग हर बार जब मैं इसे चलाता हूं तो उसी अपवाद उत्पन्न करता है - विचार किसी अन्य धागे से पुनरावृत्ति करते समय सूची को संशोधित करना है। भाग्यशाली समय के साथ, checkForComodification के बाद संशोधन ListItr#next विधि में next = next.next; से पहले होता है, जिससे एनपीई होता है।

javaapplication4.Test1.main (Test1.java:74) पर धागा "मुख्य" java.lang.NullPointerException java.util.LinkedList $ ListItr.next (LinkedList.java:891) पर एक्सेप्शन

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(); 
    } 
} 
6

यह 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; 
} 

NullPointerException इसलिए होता है क्योंकि आंतरिक चर nextnull है; हालांकि, ऐसा लगता है कि hasNext() मान्य है कि एक अगला तत्व है।

यह मेरे कि लगता है:

  • आप एक से अधिक धागा अपनी सूची को संशोधित है, या
  • आप destroy() के कार्यान्वयन में अपनी सूची को संशोधित कर रहे सूची पर पुनरावृत्ति करते हुए।

रूप @mthmulders द्वारा sugested आप destroy() के अपने कार्यान्वयन के साथ अपने जवाब अपडेट करते हैं, मैं या तो अद्यतन, सही है या मेरा उत्तर हटा दें।

संबंधित मुद्दे