所以我制作一个游戏并且每5秒就必须产生一个敌人,知道当我运行我的应用程序时它会抛出异常' ConcurrentModificationException
'。
这是我的代码的一部分:
private void tick() {
exec.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
enemyY = enemyYRand.nextInt(6);
enemy.add(new Enemy(enemyY, 10, enemyImg));
}
}, 0, 5, TimeUnit.SECONDS);
if (player.y > getHeight() - playerImg.getHeight(null)) {
player.setY(-10);
}
if (player.y < 0) {
player.setY(+10);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(Enemy enemys : enemy) {
enemys.render(g);
}
player.render(g);
}
首先调用tick方法,然后调用paintComponent方法。
这是输出:
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at _47b3n.spaceinvaders.framework.Main.paintComponent(Main.java:141)
at javax.swing.JComponent.paint(JComponent.java:1053)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5223)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:290)
at javax.swing.RepaintManager.paint(RepaintManager.java:1265)
at javax.swing.JComponent._paintImmediately(JComponent.java:5171)
at javax.swing.JComponent.paintImmediately(JComponent.java:4982)
at javax.swing.RepaintManager$4.run(RepaintManager.java:824)
at javax.swing.RepaintManager$4.run(RepaintManager.java:807)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:807)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:782)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:731)
at javax.swing.RepaintManager.access$1300(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1720)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
答案 0 :(得分:2)
您似乎有两个线程,每个线程同时在ArrayList
上运行。
其中一个是在事件调度线程中,其中调用了paintComponent
。您正在使用增强的for循环,它在内部使用Iterator
。这个迭代器正在抛出ConcurrentModificationException
。
当您致电ArrayList
时,您正在其他线程中修改tick
方法中的enemy.add(new Enemy(enemyY, 10, enemyImg));
。
Iterator
注意到ArrayList
已被修改并抛出异常。当您显示敌人时,必须具有ArrayList
的一致视图。
通过在ArrayList
块中的enemy
封闭读写操作,在某个对象(甚至可能是ArrayList
本身)上同步对此synchronized
的访问。这意味着这些块中只有一个可以同时执行。
synchronized (enemy) {
enemy.add(new Enemy(enemyY, 10, enemyImg));
}
和
synchronized (enemy) {
for(Enemy enemys : enemy) {
enemys.render(g);
}
}