如何调试ConcurrentModificationException?

我遇到了ConcurrentModificationException,通过查看它,我看不出它为什么会发生的原因; 抛出exception的区域和修改集合的所有位置都被包围

synchronized (this.locks.get(id)) { ... } // locks is a HashMap; 

我试图抓住讨厌的线程,但我所能指出的(通过在exception中设置断点)是抛出线程拥有监视器而另一个线程(程序中有两个线程)睡眠。

我该怎么办? 当遇到类似的线程问题时,您通常会做什么?

它可能与同步块无关。 当您在迭代其元素时修改集合时,经常会发生ConcurrentModificationException

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

与上一篇文章类似,如果删除条目,则可能会出现同样的问题。 例如

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

另一个常见的例子是清理Map。

可以使用Iterator明确解决此特定问题。

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

有时您的应用程序可能复杂得太复杂,某些function可能会产生太多副作用。 另外,也许另一个线程确实对该列表做错了,你无法轻易找到。

对于我自己的问题,我编写了自己的列表系统,委托另一个列表,一旦锁定,所有其他修改抛出ConcurrentModificationException,因此错误的修改指令将在输出处获得exception。 它还可以检测上述错误。

 import java.util。*;

 / **
  *由IntelliJ IDEA创建。
  *用户:francoiscassistat
  *日期:2010年7月12日
  *时间:18:20:18
  *
  *
  *可锁定列表,用于在列表上调试ConcurrentModificationException。
  *可以使用setLocked(boolean)打开/关闭锁定。
  *锁定时,对列表或迭代器的所有写访问都会获得ConcurrentModificationException。
  *简单的使用案例:
  *
  * list.setLocked(true);
  *
  * for(Object o:list.iterator())//现在这不会得到ConcurrentModificationException,导致这个的另一个指令会抛出exception
  * {...}
  *
  * list.setLocked(false);
  * /
公共类LockableList 实现List  {
     protected class LockableListIterator实现Iterator  {
         protected Iterator 迭代器;

         public LockableListIterator(Iterator  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实现ListIterator  {
         protected ListIterator  listIterator;

         public LockableListListIterator(ListIterator  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实现List 
     {
         protected List 列表;

         public LockableListSubList(List  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  iterator(){
            返回新的LockableListIterator(list.iterator());
         }

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

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

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

         @覆盖
         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  listIterator(){
             return new LockableListListIterator(list.listIterator());
         }

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

         public List  subList(int fromIndex,int toIndex){
            返回新的LockableListSubList(list.subList(fromIndex,toIndex));
         }
     }

     protected List 列表;
     protected boolean locked;

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

     public boolean isLocked(){
        返回锁定;
     }

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

     protected void checkLock(){
        如果(锁定)
            抛出新的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  iterator(){
        返回新的LockableListIterator(list.iterator());
     }

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

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

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

     @覆盖
     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  listIterator(){
         return new LockableListListIterator(list.listIterator());
     }

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

     public List  subList(int fromIndex,int toIndex){
        返回新的LockableListSubList(list.subList(fromIndex,toIndex));
     }
 }

只需像这样使用它:

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

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

 list.setLocked(假);

希望它可以帮助别人。

如果您需要从列表中删除一些元素。 您可以维护另一个列表,例如要删除的元素。 最后调用removeAll(collection)。 当然这对大数据来说并不好。

由于不得不处理类似的问题,我编写了一个小助手来调试某些对象的并发访问情况(有时使用调试器会修改运行时行为以至于不会发生问题)。 这种方法类似于Francois所展示的方法,但更为通用。 也许它有助于某人: http : //code.google.com/p/kongcurrent/

在迭代它时修改动态列表时会收到ConcurrentModificationException(例如,在foreach循环中)。 您可能希望确保在任何地方都不这样做。