2011-07-06 14 views
8

से अधिक पुनरावृत्ति जब मैं निम्नलिखित कोड निष्पादित, मैं ConcurrentModificationExceptionजावा: ConcurrentModificationException जबकि सूची

Collection<String> myCollection = Collections.synchronizedList(new ArrayList<String>(10)); 
    myCollection.add("123"); 
    myCollection.add("456"); 
    myCollection.add("789"); 
    for (Iterator it = myCollection.iterator(); it.hasNext();) { 
     String myObject = (String)it.next(); 
     System.out.println(myObject); 
     myCollection.remove(myObject); 
     //it.remove(); 
    } 

क्यों मैं अपवाद हो रही है, भले ही मैं Collections.synchronizedList उपयोग कर रहा हूँ?

जब मैं

ConcurrentLinkedQueue<String> myCollection = new ConcurrentLinkedQueue<String>(); 

को myCollection बदल रहा है कि अपवाद नहीं मिलता है।

संग्रह.सिंक्रनाइज़लिस्ट सूची से अलग java.util.concurrent में ConcurrentLinkedQueue कैसे है?

+0

[एक संग्रह के माध्यम से बार-बार दोहराना, ConcurrentModificationException परहेज जब पाश में दूर करने] (http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re) – Raedwald

उत्तर

13

सिंक्रनाइज़ सूची Iterator का नया कार्यान्वयन प्रदान नहीं करेगी। यह सिंक्रनाइज़ सूची के कार्यान्वयन का उपयोग करेगा। iterator() की implementation है:

public Iterator<E> iterator() { 
    return c.iterator(); // Must be manually synched by user! 
} 

ArrayList से:

iterators इस वर्ग के इटरेटर और listIterator तरीकों से लौट आए हैं असफल फास्ट: सूची संरचनात्मक रूप से बाद किसी भी समय संशोधित किया गया है, तो इटरेटर इटरेटर के स्वयं निकालने के माध्यम से छोड़कर बनाया जाता है, किसी भी तरह से या विधियों को जोड़ने, इटरेटर एक ConcurrentModificationException

फेंक होगा

ConcurrentLinkedQueue#iterator से:

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

iterators दो संग्रह द्वारा दिया डिजाइन से अलग हैं।

7

नहीं करते

myCollection.remove(myObject); 

कर

it.remove(); 

तुल्यकालन या समवर्ती संग्रह के लिए कोई जरूरत नहीं है

+0

मेरे की संभावित डुप्लिकेट सवाल यह है कि, दोनों अलग कैसे हैं? – vinoth

+0

@cmv, इसकी आपकी सूची के साथ कुछ लेना देना नहीं है। इसमें आपके द्वारा किए जाने पर संग्रह को संशोधित करने का प्रयास करने के साथ सबकुछ करना है। ['Iterator.remove()'] (http://download.oracle.com/javase/6/docs/api/java/util/Iterator.html#remove%28%29) आपको ऐसा करने में सक्षम बनाता है। – mre

+0

मेरा मतलब है, संग्रह नहीं है। सिंक्रनाइज़ लिस्ट ऑपरेशन परमाणु बनाने की देखभाल करते हैं ..? – vinoth

2

संग्रह से java.util.concurrent अलग में ConcurrentLinkedQueue कैसे है .synchronizedList?

उनके पास अलग-अलग कार्यान्वयन हैं, और इसलिए चुन सकते हैं कि ConcurrentModificationException को फेंकना है या आप जिस स्थिति का वर्णन करते हैं उसे संभालने के लिए। स्पष्ट रूप से सीएलक्यू सुन्दरता से संभालता है, और संग्रह। सिंक्रनाइज़लिस्ट द्वारा लिपटे ArrayList (मेरा अनुमान है कि व्यवहार ArrayList है, रैपर नहीं है) नहीं है।

जैसा कि @unbeli कहते हैं, पुनरावृत्त करते समय संग्रह नहीं, पुनरावृत्त के माध्यम से हटा दें।

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