这是防止ConcurrentModificationException的好方法

时间:2011-01-13 12:04:56

标签: java synchronization

另一个问题是同步。我在类Note中也有一个run(),因为我想每5分钟输出一次注释中的每个元素。但我总是异常:java.util.ConcurrentModificationException,如果我尝试在main中进行更多会议。所以我applay同步到列表备注,当我迭代笔记时可能会添加一个新的会议。我运行这样的方法:

在同步列表备注上是否正确,以防止ConcurrentModificationException?(在我的程序中它可以正常工作。我现在永远不会遇到此异常)

Meeting类和Note类可能喜欢这个:

public class Meeting{

    public Meeting(Note note_1,Note note_2){

                 note_1.addElement(this);

                 note_2.addElement(this);}

                 //another method hier 

                  }

public class Note implements Runnable{

    public final List<Meeting> notes = new ArrayList<Meeting>();

    public void addElement(Meeting n){

               entries.add(n);
              }

   @Override

   public void run(){
             while(true) {
             for(Meeting n : notes){

                 System.out.println(n.toString);}

                 }

             try{ Thread.sleep(10);}

             }

           }
          }

我总是得到关于异常的异常错误:java.util.ConcurrentModificationException 如果我尝试在main中进行更多会议,那么我在课堂上更改了一个小册子注意,喜欢这个:

  private  static final List<Entry> entries = Collections.synchronizedList(new ArrayList<Entry>());

并在run()

@Override
public void run() {
    while(true){
        synchronized(notes){
            for(Entry n : entries){
                 //do something
                 }
            }
            try {   
                Thread.sleep(10);  
         } catch (InterruptedException e ) {
            } 
     }
   }

}

3 个答案:

答案 0 :(得分:4)

来自javadoc

请注意,此异常并不总是表示某个对象已被另一个线程同时修改。如果单个线程发出违反对象合同的一系列方法调用,则该对象可能会抛出此异常。例如,如果一个线程在使用失败快速迭代器迭代集合时直接修改了一个集合,那么迭代器将会抛出此异常。

这意味着不要在循环中更改集合,并且即使在同一个线程中也要同时迭代它。

答案 1 :(得分:0)

阅读@Navi写的内容。

简而言之 - 永远不要为每个循环删除/添加集合的元素。

我曾经遇到过这种问题,我决定使用http://code.google.com/p/google-collections/ 那里有一些map / filter函数(如果我记得那些方法在Collections2库中)。

如果你不愿意做正确的事,你可以随时使用老式的迭代器技术。

答案 2 :(得分:0)

在我遇到这类问题之前,我曾使用CopyOnWriteArrayList

这为每次写入创建了底层数组的完整副本,因此效率不高,但我发现它对特定情况非常有用(例如,管理对其他类的专门事件通知的类)

  

这个数组在迭代器的生命周期内永远不会改变,因此干扰是不可能的,并且保证迭代器不会抛出ConcurrentModificationException