Java 解决ConcurrentModificationException
我正在写一个小游戏,其中有许多圆圈在屏幕上移动。Java 解决ConcurrentModificationException,java,thread-safety,concurrentmodification,Java,Thread Safety,Concurrentmodification,我正在写一个小游戏,其中有许多圆圈在屏幕上移动。 我在两个线程中管理圆圈,如下所示: 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
我在两个线程中管理圆圈,如下所示:
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++;
}
}
在第一个线程中。起初,我尝试使用foreach循环遍历ArrayList,这给了我相同的异常。在研究了一下这个异常之后,我看到了两个解决方案:
1.将访问集合的部分放入同步块中。
2.使用集合的迭代器对象。
他们都没有为我解决这个问题。要使
synchronized(){}
块有效,对受保护对象的所有访问必须包装在同步块中。您可能忘记包装一些访问权限
另一个“问题”是ConcurrentModificationException也可能意味着它在同一线程中被并发修改。例如,如果在遍历集合时从集合中移除元素,则可能会出现此异常。(作为一个例外,您可以通过迭代器本身安全地删除元素)ConcurrentModificationException表示您正在对集合进行迭代,并且在迭代过程中,有人(当前线程或另一个线程)修改了基础集合,而没有使用
迭代器.remove()
。无论何时调用迭代器上的操作,它都会检查底层集合是否已更改。使用foreach不会改变任何事情,因为它使用迭代器来执行循环
您的解决方案是:
非常感谢,实际上还有一个接入点我忘了包装。
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();
}
}
Circle c = it.next();