2009-05-08 18 views
11

मुझे ConcurrentModificationException का सामना करना पड़ा और इसे देखकर मैं यह नहीं देख सकता कि यह क्यों हो रहा है; क्षेत्र अपवाद और सभी स्थानों संग्रह संशोधित फेंक करConcurrentModificationException को डिबग कैसे करें?

synchronized (this.locks.get(id)) { 
    ... 
} // locks is a HashMap<String, Object>; 

मैं परेशान धागा पकड़ने की कोशिश की घिरे रहे हैं लेकिन सभी मैं (अपवाद में एक ब्रेकपाइंट सेट करके) कील सकता है कि फेंकने धागा का मालिक है मॉनिटर जबकि अन्य थ्रेड (प्रोग्राम में दो धागे हैं) सोते हैं।


मुझे आगे कैसे बढ़ना चाहिए? जब आप समान थ्रेडिंग समस्याओं का सामना करते हैं तो आप आमतौर पर क्या करते हैं?

+0

[एक संग्रह के माध्यम से बार-बार दोहराना, ConcurrentModificationException परहेज जब पाश में दूर करने] की संभावित डुप्लिकेट (http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception- कब-फिर) – Raedwald

उत्तर

30

इसमें सिंक्रनाइज़ेशन ब्लॉक से कोई लेना देना नहीं हो सकता है। ConcurrentModificationException अक्सर तब होता है जब आप अपने तत्वों पर पुनरावृत्ति करते समय संग्रह को संशोधित कर रहे होते हैं।

List<String> messages = ...; 
for (String message : messages) { 
    // Prone to ConcurrentModificationException 
    messages.add("A COMPLETELY NEW MESSAGE"); 
} 
1

यह जब एक गतिशील सूची को संशोधित इस पर पुनरावृत्ति करते हुए (उदाहरण के लिए एक foreach पाश में) एक ConcurrentModificationException प्राप्त करने के लिए आम बात है। आप यह सुनिश्चित करना चाहते हैं कि आप कहीं भी ऐसा नहीं कर रहे हैं।

11

पिछली पोस्ट की तरह, यदि आप कोई प्रविष्टि हटाते हैं तो आप एक ही समस्या प्राप्त कर सकते हैं। उदा।

for(String message : messages) { 
    if (condition(message)) 
    messages.remove(message); 
} 

एक अन्य आम उदाहरण एक मानचित्र की सफाई कर रहा है।

इस विशेष समस्या को स्पष्ट रूप से एक इटरेटर का उपयोग करके हल किया जा सकता है।

for(Iterator<String> iter = messages.iterator(); iter.hasNext();) { 
    String message = iter.next(); 
    if (condition(message)) 
     iter.remove(); // doesn't cause a ConcurrentModificationException 
} 
+1

मुझे अभी भी iter.remove() लाइन पर एक ConcurrentModificationException मिलता है। –

+1

@ErikB क्या आपने अपनी समस्या का समाधान किया? कैसे? –

+2

@ user309483 मैंने प्रदर्शन परीक्षण के बाद CopyOnWriteArray का उपयोग किया और प्रदर्शन ढूंढना हमारी आवश्यकताओं के लिए बुरा नहीं है। कुछ स्थानों पर हम toemoveSet समाधान iftee उल्लेख के साथ गए थे। –

4

यदि आप अपनी सूची में से कुछ तत्वों को नष्ट करने की जरूरत है। आप हटाए जाने वाले तत्वों की तरह एक और सूची बनाए रख सकते हैं। और अंत में हटाएं सभी (संग्रह)। बेशक यह विशाल डेटा के लिए अच्छा नहीं है।

5

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

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

 
import java.util.*; 

/** 
* Created by IntelliJ IDEA. 
* User: francoiscassistat 
* Date: 12 juin 2010 
* Time: 18:20:18 
* 
* 
* Lockable list, made to debug ConcurrentModificationException on Lists. 
* The lock can be switched on/off with setLocked(boolean). 
* When locked, all write access to the list or iterators gets ConcurrentModificationException. 
* Simple usage case : 
* 
* list.setLocked(true); 
* 
* for (Object o : list.iterator()) // now this won't get ConcurrentModificationException, the other instruction that cause this will thrown the exception 
* { ... } 
* 
* list.setLocked(false); 
*/ 
public class LockableList<E> implements List<E> { 
    protected class LockableListIterator implements Iterator<E> { 
     protected Iterator<E> iterator; 

     public LockableListIterator(Iterator<E> iterator) { 
      this.iterator = iterator; 
     } 

     public boolean hasNext() { 
      return iterator.hasNext(); 
     } 

     public E next() { 
      return iterator.next(); 
     } 

     public void remove() { 
      checkLock(); 
      iterator.remove(); 
     } 
    } 

    protected class LockableListListIterator implements ListIterator<E> { 
     protected ListIterator<E> listIterator; 

     public LockableListListIterator(ListIterator<E> listIterator) { 
      this.listIterator = listIterator; 
     } 

     public boolean hasNext() { 
      return listIterator.hasNext(); 
     } 

     public E next() { 
      return listIterator.next(); 
     } 

     public boolean hasPrevious() { 
      return listIterator.hasPrevious(); 
     } 

     public E previous() { 
      return listIterator.previous(); 
     } 

     public int nextIndex() { 
      return listIterator.nextIndex(); 
     } 

     public int previousIndex() { 
      return listIterator.previousIndex(); 
     } 

     public void remove() { 
      checkLock(); 
      listIterator.remove(); 
     } 

     public void set(E e) { 
      checkLock(); 
      listIterator.set(e); 
     } 

     public void add(E e) { 
      checkLock(); 
      listIterator.add(e); 
     } 
    } 

    protected class LockableListSubList implements List<E> 
    { 
     protected List<E> list; 

     public LockableListSubList(List<E> list) { 
      this.list = list; 
     } 

     public int size() { 
      return list.size(); 
     } 

     public boolean isEmpty() { 
      return list.isEmpty(); 
     } 

     public boolean contains(Object o) { 
      return list.contains(o); 
     } 

     public Iterator<E> iterator() { 
      return new LockableListIterator(list.iterator()); 
     } 

     public Object[] toArray() { 
      return list.toArray(); 
     } 

     public <T> T[] toArray(T[] a) { 
      return list.toArray(a); 
     } 

     public boolean add(E e) { 
      checkLock(); 
      return list.add(e); 
     } 

     public boolean remove(Object o) { 
      checkLock(); 
      return list.remove(o); 
     } 

     public boolean containsAll(Collection<?> c) { 
      return list.containsAll(c); 
     } 

     public boolean addAll(Collection<? extends E> c) { 
      checkLock(); 
      return list.addAll(c); 
     } 

     public boolean addAll(int index, Collection<? extends E> c) { 
      checkLock(); 
      return list.addAll(index, c); 
     } 

     public boolean removeAll(Collection<?> c) { 
      checkLock(); 
      return list.removeAll(c); 
     } 

     public boolean retainAll(Collection<?> c) { 
      checkLock(); 
      return list.retainAll(c); 
     } 

     public void clear() { 
      checkLock(); 
      list.clear(); 
     } 

     @Override 
     public boolean equals(Object o) { 
      return list.equals(o); 
     } 

     @Override 
     public int hashCode() { 
      return list.hashCode(); 
     } 

     public E get(int index) { 
      return list.get(index); 
     } 

     public E set(int index, E element) { 
      checkLock(); 
      return list.set(index, element); 
     } 

     public void add(int index, E element) { 
      checkLock(); 
      list.add(index, element); 
     } 

     public E remove(int index) { 
      checkLock(); 
      return list.remove(index); 
     } 

     public int indexOf(Object o) { 
      return list.indexOf(o); 
     } 

     public int lastIndexOf(Object o) { 
      return list.lastIndexOf(o); 
     } 

     public ListIterator<E> listIterator() { 
      return new LockableListListIterator(list.listIterator()); 
     } 

     public ListIterator<E> listIterator(int index) { 
      return new LockableListListIterator(list.listIterator(index)); 
     } 

     public List<E> subList(int fromIndex, int toIndex) { 
      return new LockableListSubList(list.subList(fromIndex, toIndex)); 
     } 
    } 

    protected List<E> list; 
    protected boolean locked; 

    public LockableList(List<E> list) { 
     this.list = list; 
     locked = false; 
    } 

    public boolean isLocked() { 
     return locked; 
    } 

    public void setLocked(boolean locked) { 
     this.locked = locked; 
    } 

    protected void checkLock() { 
     if (locked) 
      throw new ConcurrentModificationException("Locked"); 
    } 

    public int size() { 
     return list.size(); 
    } 

    public boolean isEmpty() { 
     return list.isEmpty(); 
    } 

    public boolean contains(Object o) { 
     return list.contains(o); 
    } 

    public Iterator<E> iterator() { 
     return new LockableListIterator(list.iterator()); 
    } 

    public Object[] toArray() { 
     return list.toArray(); 
    } 

    public <T> T[] toArray(T[] a) { 
     return list.toArray(a); 
    } 

    public boolean add(E e) { 
     checkLock(); 
     return list.add(e); 
    } 

    public boolean remove(Object o) { 
     checkLock(); 
     return list.remove(o); 
    } 

    public boolean containsAll(Collection<?> c) { 
     return list.containsAll(c); 
    } 

    public boolean addAll(Collection<? extends E> c) { 
     checkLock(); 
     return list.addAll(c); 
    } 

    public boolean addAll(int index, Collection<? extends E> c) { 
     checkLock(); 
     return list.addAll(index, c); 
    } 

    public boolean removeAll(Collection<?> c) { 
     checkLock(); 
     return list.removeAll(c); 
    } 

    public boolean retainAll(Collection<?> c) { 
     checkLock(); 
     return list.retainAll(c); 
    } 

    public void clear() { 
     checkLock(); 
     list.clear(); 
    } 

    @Override 
    public boolean equals(Object o) { 
     return list.equals(o); 
    } 

    @Override 
    public int hashCode() { 
     return list.hashCode(); 
    } 

    public E get(int index) { 
     return list.get(index); 
    } 

    public E set(int index, E element) { 
     checkLock(); 
     return list.set(index, element); 
    } 

    public void add(int index, E element) { 
     checkLock(); 
     list.add(index, element); 
    } 

    public E remove(int index) { 
     checkLock(); 
     return list.remove(index); 
    } 

    public int indexOf(Object o) { 
     return list.indexOf(o); 
    } 

    public int lastIndexOf(Object o) { 
     return list.lastIndexOf(o); 
    } 

    public ListIterator<E> listIterator() { 
     return new LockableListListIterator(list.listIterator()); 
    } 

    public ListIterator<E> listIterator(int index) { 
     return new LockableListListIterator(list.listIterator(index)); 
    } 

    public List<E> subList(int fromIndex, int toIndex) { 
     return new LockableListSubList(list.subList(fromIndex, toIndex)); 
    } 
} 

बस इस तरह उपयोग:

 
List list = new LockableList(new ArrayList(...)); 
list.setLocked(true); 

for (E e : list.iterator()) 
{ ... } 

list.setLocked(false); 

आशा है कि यह किसी और मदद मिल सकती है।

2

इसी तरह के मुद्दों से निपटने के लिए मैंने कुछ वस्तुओं पर समवर्ती पहुंच स्थितियों को डीबग करने के लिए एक छोटा सा सहायक लिखा था (कभी-कभी डीबगर का उपयोग रनटाइम व्यवहार को इतना आसान करता है कि समस्या नहीं होती है)। दृष्टिकोण फ्रैंकोइस के समान है, लेकिन थोड़ा और सामान्य है। शायद यह मदद करता है किसी को: http://code.google.com/p/kongcurrent/

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