2013-03-15 7 views
8

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

synchronized(mapItems) { 
    Iterator<MapItem> iterator = mapItems.iterator(); 
    while(iterator.hasNext()) 
     iterator.next().draw(g); 
} 

mapItems एक सिंक्रनाइज़ संग्रह है: वेक्टर। क्या यह पर ConcurrentModificationException से सुरक्षित है?

+1

क्या आपको स्वीकार करने का कोई सही जवाब मिला है ?? – AmitG

उत्तर

3

हां, यह ConcurrentModificationException से अनिवार्य रूप से एकल-थ्रेडेड होने की कीमत पर इसे सुरक्षित बनाएगा।

2

हाँ, मुझे विश्वास है कि यह ConcurrentModificationException को रोक देगा। आप Vector पर सिंक्रनाइज़ कर रहे हैं। Vector पर सभी विधियां जो इसे संशोधित करती हैं synchronized भी हैं, जिसका अर्थ है कि वे उसी ऑब्जेक्ट को भी लॉक करेंगे। तो जब आप इसे फिर से चालू कर रहे हों तो कोई अन्य धागा Vector को बदल सकता है।

इसके अलावा, आप Vector को संशोधित नहीं कर रहे हैं, जबकि आप इसे फिर से चालू कर रहे हैं।

1

आप रीडवाइट लॉक का उपयोग करने पर विचार करना चाह सकते हैं।

प्रक्रियाओं के लिए जो इसकी सामग्री को संशोधित किए बिना सूची में पुन: सक्रिय होते हैं, साझा ReentrantReadWriteLock पर एक रीड लॉक प्राप्त करें। यह कई धागे को लॉक तक पहुंच पढ़ने की अनुमति देता है।

उन प्रक्रियाओं के लिए जो सूची को संशोधित करेंगे, साझा लॉक पर लिखें लॉक प्राप्त करें। यह सभी अन्य धागे को सूची तक पहुंचने से रोक देगा (यहां तक ​​कि केवल पढ़ने के लिए) जब तक कि आप लिखने के लॉक को छोड़ नहीं देते।

1

क्या यह समवर्ती मोडिफिकेशन अपवाद से वेक्टर सुरक्षित पर पुनरावृत्ति कर रहा है?

हाँ यह है.अगर यह उस मामले में तो संबद्ध नहीं है वेक्टर से अधिक बार-बार दोहराना ConcurrentModificationException से सुरक्षित बनाता है अगर आप विभिन्न धागे के माध्यम से वेक्टर एक्सेस कर रहे हैं और कुछ अन्य थ्रेड संरचना की दृष्टि से किसी में वेक्टर संशोधित कर रहा है इटरेटर बनने के बाद, इटेटरेटर ConcurrentModificationException फेंक देगा। जबकि निष्पादन अपने सिस्टम पर

import java.util.*; 
class VVector 
{ 
    static Vector<Integer> mapItems = new Vector<Integer>(); 
    static 
    { 
     for (int i = 0 ; i < 200 ; i++) 
     { 
      mapItems.add(i); 
     } 
    } 
    public static void readVector() 
    { 
     Iterator<Integer> iterator = mapItems.iterator(); 
     try 
     { 
      while(iterator.hasNext()) 
      { 
       System.out.print(iterator.next() + "\t"); 
      } 
     } 
     catch (Exception ex){ex.printStackTrace();System.exit(0);} 
    } 
    public static void main(String[] args) 
    { 
     VVector v = new VVector(); 
     Thread th = new Thread(new Runnable() 
     { 
      public void run() 
      { 
       int counter = 0; 
       while (true) 
       { 
        mapItems.add(345); 
        counter++; 
        if (counter == 100) 
        { 
         break; 
        } 
       } 
      } 
     }); 
     th.start(); 
     v.readVector(); 

    } 
} 

यह निम्न उत्पादन दिखा रहा है::

0  1  2  3  4  5  6  7  8  9 
java.util.ConcurrentModificationException 
     at java.util.AbstractList$Itr.checkForComodification(Unknown Source) 
     at java.util.AbstractList$Itr.next(Unknown Source) 
     at VVector.readVector(VVector.java:19) 
     at VVector.main(VVector.java:38) 

लेकिन आपको लगता है कि Vector तक पहुँचने के लिए Iterator युक्त कोड के ब्लॉक बनाने अगर दूसरी ओर सिंक्रनाइज़ इस कोड को चलाने पर विचार mapItems लॉक के रूप में उपयोग करते हुए, यह Vector से संबंधित अन्य विधियों के निष्पादन को रोक देगा जब तक कि synchronized ब्लॉक परमाणु रूप से पूरा नहीं हो जाता है।

2

बस पूरे संग्रह को सिंक्रनाइज़ करने से ConcurrentModificationException को रोका नहीं जाएगा। यह अभी भी एक सीएमई

synchronized(mapItems) { 
    for(MapItem item : mapsItems){ 
     mapItems.add(new MapItem()); 
    } 
} 
0

अगर हम लूप के दौरान अंदर विधि जोड़ते हैं तो अपवाद फेंकता है।

synchronized(mapItems) { 
    Iterator<MapItem> iterator = mapItems.iterator(); 
    while(iterator.hasNext()) 
     iterator.next(); 
     mapItems.add("Something"); // throws ConcurrentModificationException 
} 
संबंधित मुद्दे