Java:Java.util.ConcurrentModificationException
我正在制作2D,目前正在进行子弹射击。子弹是一个单独的类。所有项目符号都存储在名为“项目符号”的arraylist中。我试图让它在屏幕外侧(<-16)时破坏自己,但当我尝试时,它会给我这个错误Java:Java.util.ConcurrentModificationException,java,arraylist,Java,Arraylist,我正在制作2D,目前正在进行子弹射击。子弹是一个单独的类。所有项目符号都存储在名为“项目符号”的arraylist中。我试图让它在屏幕外侧(-16){ x-=移动速度; }否则{ ObjectHandler.记住要杀死(这个); } } //在ObjectHandler中: 私有HashSet kill_memory=new。。。; 公共空间{ this.kill_memory.add(this); } 私有void从_内存中杀死_(){ for(类型为\u对象的\u到\u kill obj:k
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at GameCanvas.updateMovement(GameCanvas.java:94)
at GameCanvas.gameLoop(GameCanvas.java:63)
at GameCanvas.<init>(GameCanvas.java:28)
at GameClient.<init>(GameClient.java:68)
at GameClient.main(GameClient.java:29)
updateMovement()方法:
为什么要这样做?谢谢。当您在列表中迭代并试图同时从列表中删除/修改某个项目时,通常会引发此问题。我不确定到底发生了什么事。更多的代码示例可能会有所帮助。之所以会出现这种情况,是因为您在迭代列表时正在修改列表 试着“记住”你需要的
kill
,在你通过整个列表后,检查你的“记忆”并执行相应的kill
s。通过这种方式,您将在遍历列表后修改它
例如:
公共作废移动(){
如果(x>-16){
x-=移动速度;
}否则{
ObjectHandler.记住要杀死(这个);
}
}
//在ObjectHandler中:
私有HashSet kill_memory=new。。。;
公共空间{
this.kill_memory.add(this);
}
私有void从_内存中杀死_(){
for(类型为\u对象的\u到\u kill obj:kill\u内存){
ObjectHandler.bullets.remove(此);
}
ObjectHandler.kill_memory.clear();
}
//更新运动:
public void updateMovement(){
PlayerObject.update();
for(项目符号:ObjectHandler.bullets){
bullet.move();
}
ObjectHandler.kill_from_memory();
}
从堆栈跟踪中,我们可以看到您有一个方法,gameLoop()
在GameCanvas
中调用updateMovement()
。后者迭代main
线程中的项目符号。同时,您的kill()
方法修改列表。这正是异常所说的,可以防止您受到进一步的损害
您必须同步访问
项目符号
列表或使用线程安全集合,如。问题在于,您试图修改集合,同时在读取时删除元素。当然,这可能很危险,因此会抛出异常。如果使用迭代器
,则可以利用其函数删除当前元素
大概是这样的:
public void updateMovement() {
PlayerObject.update();
Iterator<Bullet> iterator = ObjectHandler.bullets.iterator();
while(iterator.hasNext()) {
Bullet bullet = iterator.next();
if(x > -16) {
x -= move_speed;
} else {
iterator.remove();
}
}
}
public void updateMovement(){
PlayerObject.update();
Iterator Iterator=ObjectHandler.bullets.Iterator();
while(iterator.hasNext()){
Bullet=iterator.next();
如果(x>-16){
x-=移动速度;
}否则{
iterator.remove();
}
}
}
我们可能需要查看updateMovement
源代码来帮助您。谢谢,是的,我使用了另一个ArrayList来存储射程之外的子弹,然后在移动循环后销毁它们。另外,请考虑使用其中之一,他们自动解决这个问题(尽管代价是线程安全)。
public void updateMovement() {
PlayerObject.update();
for(Bullet bullet : ObjectHandler.bullets) {
bullet.move();
}
}
public void move() {
if(x > -16) {
x -= move_speed;
} else {
ObjectHandler.remember_to_kill(this);
}
}
// in ObjectHandler:
private HashSet<type_of_object_to_kill> kill_memory = new...;
public void remember_to_kill() {
this.kill_memory.add(this);
}
private void kill_from_memory() {
for (type_of_object_to_kill obj: kill_memory) {
ObjectHandler.bullets.remove(this);
}
ObjectHandler.kill_memory.clear();
}
// update movement:
public void updateMovement() {
PlayerObject.update();
for(Bullet bullet : ObjectHandler.bullets) {
bullet.move();
}
ObjectHandler.kill_from_memory();
}
public void updateMovement() {
PlayerObject.update();
Iterator<Bullet> iterator = ObjectHandler.bullets.iterator();
while(iterator.hasNext()) {
Bullet bullet = iterator.next();
if(x > -16) {
x -= move_speed;
} else {
iterator.remove();
}
}
}