我正在写一个小游戏,屏幕上有很多圈子
我在两个主题中管理圈子如下:
public void run() {
int stepCount = 0;
int dx;
int dy;
while (m_threadTrap){
dx = 0;
dy = 0;
synchronized (m_circles) {
for (Iterator<Circle> it = m_circles.iterator(); it.hasNext();){
Circle c = it.next(); //Exception thrown here.
if (c.getDirX() != 0)
if (stepCount % c.getDirX() == 0){
dx = 1;
}
if (c.getDirY() != 0)
if (stepCount % c.getDirY() == 0){
dy = 1;
}
c.move(dx, dy);
}
}
if (stepCount == 150000){
stepCount = 0;
}
stepCount++;
}
}
圈子的ArrayList中的m_circles。
以下主题:
public void run() {
while (m_threadTrap){
int topPosition;
int bottomPosition;
int leftPosition;
int rightPosition;
ArrayList<Circle> removedCircles = new ArrayList<Circle>();
synchronized (m_circles.getCircles()) {
for (Iterator<Circle> it = m_circles.getCircles().iterator(); it.hasNext();){
Circle c = it.next();
// Some calculation to evaluate which circles should be removed
removedCircles.add(c);
}
}
}
try{
Thread.sleep(25);
}
catch (Exception e) { }
m_circles.getCircles().removeAll(removedCircles);
if (m_circles.getCircles().size() < 30)
m_circles.addNewCircle();
repaint();
}
}
我的问题是我在
行获得了ConcurrentModificationExceptionCircle c = it.next();
在第一个帖子中。起初我尝试使用foreach循环遍历ArrayList,这给了我同样的例外
在研究了这个例外之后,我看到了两个解决方案:
1.将访问集合的部分放在同步块中
2.使用集合的Iterator对象
他们俩都没有为我解决。
答案 0 :(得分:1)
要使synchronized() {}
块有效,对受保护对象的所有访问必须包含在同步块中。你可能忘了包装一些访问权。
另一个“问题”是ConcurrentModificationException也意味着它在同一个线程中同时修改了 。例如,如果在遍历集合时从集合中删除元素,则可能会出现此异常。 (作为例外,您可以通过迭代器本身安全地删除元素)
答案 1 :(得分:1)
ConcurrentModificationException意味着您正在迭代一个集合,并且在迭代时,某人(当前线程或另一个)修改了底层集合而不使用Iterator.remove()
。每当您在Iterator上调用一个操作时,它都会检查底层集合是否未被更改。使用foreach不会改变任何东西,因为它使用Iterator来执行循环。
您的解决方案是:
创建一个新集合:
for(Circle c:new ArrayList(m_circles.getCircles())。iterator()){ //一些计算来评估应删除哪些圆圈 removedCircles.add(C); }
或同步同一对象上的两个线程(您在不同对象上同步,因此它不会执行任何操作)