2010年java并发修改异常崩溃

use*_*497 4 java thread-safety

绘制存储在ArrayList中的一些粒子.这段代码工作正常:


 super.paintComponent(g);
             for (Particle b: particleArr){
                  g.setColor(b.getColor());
                  g.fillOval(b.getXCoor() + 5,b.getYCoor(),
                             b.getParticleSize(),b.getParticleSize());
             }
但是,此代码会引发并发修改异常:

        public void paintComponent(Graphics g){
            //paint particles
             super.paintComponent(g);
             for (Particle b: particleArr){
                  g.setColor(b.getColor());
                  if (b.isDead())
                      particleArr.remove(b);
                  else if (!b.isVanishing())
                      g.fillOval(b.getXCoor(),b.getYCoor(),
                            b.getParticleSize(),b.getParticleSize());
                  else {
                      g.fillOval(b.getXCoor() + 5,b.getYCoor(),
                             b.getParticleSize(),b.getParticleSize());
                      g.fillOval(b.getXCoor() - 5,b.getYCoor(),
                             b.getParticleSize(),b.getParticleSize());
                      g.fillOval(b.getXCoor(),b.getYCoor() + 5,
                             b.getParticleSize(),b.getParticleSize());
                      g.fillOval(b.getXCoor(),b.getYCoor() - 5,
                             b.getParticleSize(),b.getParticleSize());
                  }
             }
我很困惑.这是迭代器的乱码,运行缓慢.

            itr = particleArr.iterator();

         super.paintComponent(g);
         while (itr.hasNext()){
             particle=itr.next();
              g.setColor(particle.getColor());
              if (particle.isDead())
                  itr.remove();
              else if (particle.isVanishing())
                  g.fillOval(particle.getXCoor(),particle.getYCoor(),
                        particle.getParticleSize(),particle.getParticleSize());
              else {
                  g.fillOval(particle.getXCoor() + 5,particle.getYCoor(),
                         particle.getParticleSize(),particle.getParticleSize());
                  g.fillOval(particle.getXCoor() - 5,particle.getYCoor(),
                         particle.getParticleSize(),particle.getParticleSize());
                  g.fillOval(particle.getXCoor(),particle.getYCoor() + 5,
                         particle.getParticleSize(),particle.getParticleSize());
                  g.fillOval(particle.getXCoor(),particle.getYCoor() - 5,
                         particle.getParticleSize(),particle.getParticleSize());
              }
Run Code Online (Sandbox Code Playgroud)

3ur*_*och 14

尝试从数组列表中获取Iterator,然后在迭代器上调用remove()方法以删除该项.

Iterator itr = particleArr.iterator();
while(itr.hasNext()) {
   Particle b = (Particle)itr.next();
   if (b.isDead())
      itr.remove();
}
Run Code Online (Sandbox Code Playgroud)

编辑:只是使示例与您的代码更相关.

  • +1:如果要在迭代时删除元素,则需要显式使用Iterator,而不是使用幕后使用的每个语法. (3认同)
  • +1,这里是[文档](http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html)说:"这个类的迭代器和listIterator返回的迭代器方法是快速失败的:如果在创建迭代器之后的任何时候对列表进行结构修改,除了通过迭代器自己的remove或add方法之外,迭代器将抛出ConcurrentModificationException. (3认同)