日期:2014-05-20  浏览次数:20884 次

java线程锁同步问题,刚接触线程锁,出错了,代码很少,请看
[code=java
/**
 * 被打的人
 * 
 * @author zhaozhantao@21cn.com
 * 
 */
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]

------解决方案--------------------
你看看
在执行for (Collideable collideable : collideables) {}的时候
里面的代码,比如
collideEvent.setCollideable(collideable);
collideListener.onCollide(collideEvent);

这两句会不会去调用addCollideable或者removeCollideable

或者对collideables执行其他删除、添加元素的方法。

在你遍历的时候collideables,如果有这种操作,就会产生java.util.ConcurrentModificationException 
这个我以前碰到过。
------解决方案--------------------
引用:
引用:你看看
在执行for (Collideable collideable : collideables) {}的时候
里面的代码,比如
collideEvent.setCollideable(collideable);
collideListener.onCollide(collideEvent);

这两句会不……

问题不在synchronized 而在于 你对集合遍历的时候的对集合元素进行了删除操作 即使你锁了,也是不允许这么做的。
不知道你能否理解
------解决方案--------------------
你可以再定义一个集合private List<Collideable> collideables2 = new ArrayList<Collideable>();把原来的集合copy过来collideables2 = collideables?然后对这个集合进行遍历for(int i=0;i<collideables2.size();i++),获取对象的时候通过索引i去获取,注意你循环里面的操作对象通过i去原来的集合collideables里面拿,就是collideables.get(i)
------解决方案--------------------
在遍历ArrayList的时候,对它进行add,remove等操作就会报ConcurrentModificationException异常,因为原来的结构已经改变,为了防止将来可能出现的未知的错误,java提前抛出这个异常,来提示你数据结构已经改变,如果想要不抛出这个异常,可以使用迭代器的remove方法,跟锁应该是没有关系的,整个程序也没有看到多线程的地方。