2011-05-19 19 views
7

मैं इटरेटर के साथ कोड के एक टुकड़े पर काम कर रहा हूँ और जब मैं windows--फेंक है ConcurrentModificationException प्रणाली निर्भर

LinkedList ll =new LinkedList(); 
    . . . 
    . . . 
    Iterator iter = ll.iterator(); 
    int i=0; 
    while (iter.hasNext()) { 
     // GrammarSection agrammarSection = (GrammarSection) iter.next(); //a 
     String s1 = (String) iter.next(); 
     ll.remove(i); 
     i++; 
    } 

यह आशा की जाती है पर मेरी आईडीई से कार्यक्रम चलाने लाइन एक पर एक ConcurrentModificationException हो रही है क्योंकि इम जब मैं पुनरावृत्ति कर रहा हूं, तो सूची को संशोधित करना ताकि विफल-तेज़ इटेटरेटर एक Concurrentmodification अपवाद फेंकता है। हालांकि, जब मैं अपाचे सर्वर के साथ यूनिक्स में यह कोड चलाता हूं, तो इटरेटर की अगली विधि किसी भी अपवाद को फेंक नहीं देती है। तो, क्या concurrentmodification अपवाद ओएस स्तर पर निर्भर करता है?

+0

क्या आप सुनिश्चित हैं कि आपका जेडीके, कोड और डेटा दोनों वातावरण में समान हैं? मुझे खेद है, लेकिन मुझे विश्वास नहीं है कि यह संभव है। जावा क्रॉस-प्लेटफॉर्म है। ConcurrentModificationException संग्रह से फेंक दिया गया है, यानी जावा में लिखित जेडीके से, इसलिए प्लेटफ़ॉर्म पर निर्भर नहीं हो सकता है। – AlexR

+0

आपको पिछले उत्तरों को स्वीकार करना चाहिए .. –

उत्तर

3

नहीं, यह नहीं होना चाहिए। वैसे भी इसे दुर्घटनाग्रस्त होना चाहिए।

मुझे लगता है कि यह एक अलग जेवीएम पर अलग हो सकता है, लेकिन official spec के अनुसार, लिंक्ड सूची पर इटरेटर विफल-तेज होना चाहिए।

ओएस के पास इसके साथ कुछ लेना देना नहीं है।

1

मुझे पता चला कि समस्या क्या हो सकती है। जब आपकी सूची में 2 तत्व होते हैं, तो hasNext()false देता है और यह अपवाद के बिना काम करता है। यदि सूची में 3 या अधिक तत्व हैं तो यह हर जगह अपवाद फेंकता है। तो सुनिश्चित करें कि आपकी सूची में तत्वों की सही संख्या है।

ओएस निर्भरता के लिए के रूप में - जावा कोड ओएस निर्भर नहीं है

वैसे भी - अपवाद पैदा करने के बिना यह अंतर्निहित सूची से तत्व निकाल देंगे - iter.remove() का उपयोग करें।

आपके दृष्टिकोण के साथ समस्या यह है कि आप उस संशोधन के बारे में कुछ भी जानते हुए बिना अंतर्निहित सूची को संशोधित कर रहे हैं। तो आपको इसे इटरेटर के माध्यम से ले जाना होगा।

+1

यह एक टिप्पणी है, उत्तर नहीं ... ओपी का सवाल यह है कि यदि कोमो का फेंकना या नहीं, तो ओएस विशिष्ट है। मेरे लिए एक बहुत अच्छा सवाल :) – SyntaxT3rr0r

+0

हाँ, मेरे पास अब इसके बारे में एक अनुच्छेद है। – Bozho

0

iter.remove() का उपयोग करें; ll.remove नहीं (i)

आप इटरेटर निकालें समारोह का उपयोग करते हैं, तो आप एक concurrentmodificationexception नहीं मिलेगा।

हालांकि, आपके प्रश्न का उत्तर देने के लिए; सीएमई ओएस स्तर पर निर्भर नहीं होना चाहिए। आपके कोड के साथ कुछ अन्य समस्या होनी चाहिए कि यह यूनिक्स में सीएमई क्यों नहीं फेंक रहा है।

Btw, कल्पना निम्नलिखित टिप्पणी

है "नोट पुनरावर्तक की असफल फास्ट व्यवहार की गारंटी है कि नहीं किया जा सकता के रूप में यह है, आम तौर पर बोल रहा है, असंभव अनसिंक्रनाइज़्ड समवर्ती संशोधन की उपस्थिति में किसी भी मुश्किल की गारंटी देता है बनाने के लिए विफल-फास्ट इटेटरेटर सर्वोत्तम प्रयास के आधार पर ConcurrentModificationException को फेंक देते हैं। इसलिए, इस अपवाद पर निर्भर होने वाले प्रोग्राम को लिखना गलत होगा: इटरेटर्स के असफल-तेज़ व्यवहार का उपयोग केवल बग का पता लगाने के लिए किया जाना चाहिए। "

+0

मुझे बहुत अच्छी तरह पता है कि अपवाद क्यों आ रहा है और इसे कैसे हटाया जा सकता है। मेरा सवाल यह है कि जब मैं यूनिक्स पर्यावरण पर चलता हूं तो मुझे अपवाद क्यों नहीं मिल रहा है? – user496934

+0

मेरा प्रश्न है कि concurrentmodification अपवाद ओएस स्तर पर निर्भर करता है? – user496934

+0

उत्तर नहीं है। यूनिक्स एनवी में सीएमई को फेंकने के कारण कुछ अन्य कारक होना चाहिए। –

0

तो, क्या समवर्तीकरण अपवाद ओएस स्तर पर निर्भर करता है?

इसमें कुछ जेएमवी-निर्भरता है, लेकिन आपके द्वारा दिखाए गए कोड में नहीं।

// LinkedLists have a member variable called modCount 
// which is an integer which holds the count of modifications 
// made on the list with methods like list.add() list.remove() etc. 
LinkedList ll =new LinkedList(); 
. . . 
. . . 
// When the iterator is created here, it copies the current modCount 
// of the LinkedList into a member of its own called expectedModCount 
Iterator iter = ll.iterator(); 
int i= 0; 
while (iter.hasNext()) { 
    // iter.next() calls a method called checkForComodification 
    // which throws a ConcurrentModificationException if the 
    // current modCount of the original LinkedList is different 
    // from the expectedModCount on this iterator 
    String s1 = (String) iter.next(); 
    ll.remove(i); 
    i++; 
} 

जब सूची पहुँचा और उचित बिना तुल्यकालन के विभिन्न धागे में दोहराया जाता है, LinkedList.modCount के लिए किए गए संशोधन (जब LinkedList.add, LinkedList.remove आदि कहा जाता है) धागा यात्रा कर को दिखाई नहीं हो सकता है।तो ConcurrentModificationException एस सामान्य रूप से फेंकने की गारंटी नहीं है। लेकिन आपके द्वारा दिखाए गए सिंगल-थ्रेडेड कोड में, कोई दृश्यता समस्या नहीं होनी चाहिए और अगर ll.remove() को ll.iterator() के बाद सफलतापूर्वक बुलाया जाता है तो अपवाद हमेशा फेंक दिया जाना चाहिए।

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