[code=java
/**
 * 被打的人
 * 
 * @author [email protected]
 * 
 */
public class ManBall extends Spirit { /**
 * 能被碰撞的东西
 */
private List<Collideable> collideables = new ArrayList<Collideable>();@Override
public void move(float x, float y) {
synchronized (collideables) {

if (collideables != null) {
for (Collideable collideable : collideables) {
if (collideable.checkCollide(this, (int) x, (int) y)) {
CollideEvent collideEvent = new CollideEvent();
collideEvent.setCollideable(collideable);
collideListener.onCollide(collideEvent);
}
}
}
}

super.move(x, y);
}
][/code]

解决方案 »

  1.   

    不好意思,刚才一激动,点错了
    看下面的代码
    /**
     * 被打的人
     * 
     * @author [email protected]
     * 
     */
    public class ManBall extends Spirit { /**
     * 能被碰撞的东西
     */
    private List<Collideable> collideables = new ArrayList<Collideable>();
    @Override
    public void move(float x, float y) {
    if (collideListener != null) {
    synchronized (collideables) {

    if (collideables != null) {
    for (Collideable collideable : collideables) {
    if (collideable.checkCollide(this, (int) x, (int) y)) {
    CollideEvent collideEvent = new CollideEvent();
    collideEvent.setCollideable(collideable);
    collideListener.onCollide(collideEvent);
    }
    }
    }
    }
    }
    super.move(x, y);
    }

    /**
     * 添加一个要被检测的可碰撞的东西
     * 
     * @param collideable
     */
    public void addCollideable(Collideable collideable) {
    synchronized (collideables) {
    collideables.add(collideable);
    }
    }
    /**
     * 删除一个要被检测的可碰撞的东西
     * 
     * @param collideable
     */
    public void removeCollideable(Collideable collideable) {
    synchronized (collideables) {
    collideables.remove(collideable);
    }
    }
    }
      

  2.   

    三个主要的方法,分别是move,add,removemove里面遍历了这个集合
    add和remove分别是对这个集合的增加删除操作
    我都加了synchronized (collideables) 
    不知道是不是这样写,反正是执行remove的时候报了这样的一个错
    java.util.ConcurrentModificationException
      

  3.   

    你看看
    在执行for (Collideable collideable : collideables) {}的时候
    里面的代码,比如
    collideEvent.setCollideable(collideable);
    collideListener.onCollide(collideEvent);这两句会不会去调用addCollideable或者removeCollideable或者对collideables执行其他删除、添加元素的方法。在你遍历的时候collideables,如果有这种操作,就会产生java.util.ConcurrentModificationException 
    这个我以前碰到过。
      

  4.   

    确实调用了remove
    怎么解决呢?我已经用synchronized 锁住了呀,锁住还不能执行remove吗?
      

  5.   

    问题不在synchronized 而在于 你对集合遍历的时候的对集合元素进行了删除操作 即使你锁了,也是不允许这么做的。
    不知道你能否理解
      

  6.   

    你可以再定义一个集合private List<Collideable> collideables2 = new ArrayList<Collideable>();把原来的集合copy过来collideables2 = collideables 然后对这个集合进行遍历for(int i=0;i<collideables2.size();i++),获取对象的时候通过索引i去获取,注意你循环里面的操作对象通过i去原来的集合collideables里面拿,就是collideables.get(i)
      

  7.   

    也许解释的不是很明白。
    我再说的通俗一点吧。你是一个线程,我也是一个线程。
    第一种情况
    比如你负责遍历集合,我往集合离插入或者删除元素。
    现在你锁了对象锁,开始遍历。我要执行插入或者删除元素时,发现拿不到锁。要等你遍历完了释放了,我在往操作。这种情况是没问题的。第二种情况
    你自己拿了锁,开始遍历集合。在循环中,你自己对集合进行了插入或者删除元素(你自己描述的:确实调用了remove)。这种情况是会报java.util.ConcurrentModificationException 的
      

  8.   

    在遍历ArrayList的时候,对它进行add,remove等操作就会报ConcurrentModificationException异常,因为原来的结构已经改变,为了防止将来可能出现的未知的错误,java提前抛出这个异常,来提示你数据结构已经改变,如果想要不抛出这个异常,可以使用迭代器的remove方法,跟锁应该是没有关系的,整个程序也没有看到多线程的地方。
      

  9.   

    你虽然使用了同步代码块,但是 数据存储 的 ArrayList是 非线程安全的