所以我正在制作一个游戏,每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);
}首先调用刻度方法,然后调用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)发布于 2016-01-28 19:50:57
您似乎有两个线程同时在一个ArrayList上操作。
其中之一在事件分派线程中,其中调用了paintComponent。您使用的是增强的for循环,它在内部使用Iterator。这个迭代器就是抛出ConcurrentModificationException的东西。
在调用ArrayList时,您正在修改tick方法中的enemy.add(new Enemy(enemyY, 10, enemyImg));,以及其他线程中的enemy.add(new Enemy(enemyY, 10, enemyImg));。
Iterator注意到ArrayList被修改了,并抛出了异常。当您显示敌人时,必须对您的ArrayList有一个一致的视图。
通过在ArrayList块中包含对该ArrayList的读和写操作,同步对某些对象(甚至是enemy本身)上的ArrayList的访问。这意味着这些块中只有一个可以同时执行。
synchronized (enemy) {
enemy.add(new Enemy(enemyY, 10, enemyImg));
}和
synchronized (enemy) {
for(Enemy enemys : enemy) {
enemys.render(g);
}
}https://stackoverflow.com/questions/35070495
复制相似问题