gpt4 book ai didi

java - 暂停线程以防止 ConcurrentModificationException?

转载 作者:行者123 更新时间:2023-12-03 06:22:48 26 4
gpt4 key购买 nike

我正在创建一个 Swing 应用程序来制作游戏。它在屏幕外的随机位置创建图像,当它们离开屏幕时我想将它们删除。请看一下代码片段:

public void checkTrolls(){ //CAUSES EXCEPTION ERROR WHEN SPRITE EXIT SCREEN
for(AutomatedSprite a : trolls){
if(a.getX() < 0 - a.getImage().getWidth())
trolls.remove(a);
if(a.getY() < 0 - a.getImage().getWidth())
trolls.remove(a);
if(a.getX() > 800)
trolls.remove(a);
if(a.getY() > 600)
trolls.remove(a);
}
}

@Override
public void run() {
long beforeTime, timeDiff, sleep;

beforeTime = System.currentTimeMillis();

while(true){
dodger.update(); //update sprite
if(trolls.size() != 6){
trolls.add(new AutomatedSprite("images/troll_face.png"));
}
for(Sprite troll : trolls){
troll.update(); //UPDATES MY SPRITES
}
checkTrolls(); //CHECKS TROLLS EXITING THE SCREEN
repaint();

for(Sprite troll : trolls){
System.out.println("X: " + troll.getX());
System.out.println("Y: " + troll.getY());
}

timeDiff = System.currentTimeMillis() - beforeTime;
sleep = timeDiff - DELAY;

if(sleep < 0)
sleep = 5;

try {
Thread.sleep(sleep);
} catch (InterruptedException e) { e.printStackTrace(); }

beforeTime = System.currentTimeMillis();
}
}

trolls 是 AutomatedSprites 的 vector ,当它们离开屏幕时,我收到 ConcurrentModificationException,显然我无法从 vector 中删除实例。

所以,当线程更新我的所有 Sprite 时,我似乎无法从 vector 中删除任何内容,有没有办法暂停我的线程,以便我可以删除 Sprite ?

P.S:这是全类同学以防万一我错过了什么:Pastebin

最佳答案

在迭代集合时无法从集合中删除,对于单线程环境和多线程环境都是如此。 syncrhonized 仍然会导致问题,Thread.sleep 也是如此。使用迭代器并以这种方式删除。

public void checkTrolls(){
for(Iterator<AutomatedSprite> itr = trolls.iterator(); itr.hasNext();){
AutomatedSpring nextElemnt = itr.next();
if(youShouldRemoveTheSprite){
itr.remove();
}
}
}

因此,您在这里使用 trolls 集合提供的迭代器。并且您要求迭代器从集合中安全地删除对象。

现在,如果您使用多个线程执行 checkTrolls,那么您将需要同步。你可以这样做

public synchronized void checkTrolls(){ ...

根据您最近的评论/链接进行编辑

这并不是说您将 Iterator.next() 分配给了一个变量,而是您多次调用了 iterator.next() 。每次调用 next() 时,您都会将迭代器移动到列表的下一个元素。因此,在一次循环迭代结束时,您将迭代器移动到列表中的第 6 个元素。如果您对它建立索引,它会看起来像:

   for(Iterator<AutomatedSprite> itr = trolls.iterator(); itr.hasNext(); ){
if(trolls.get(0).getX() < 0 - trolls.get(1).getImage().getWidth() ||
trolls.get(2).getY() < 0 - trolls.get(3).getImage().getWidth() ||
trolls.get(4).getX() > 800 ||
trolls.get(5).getY() > 600){
trolls.remove(trolls.get(5));
}

此示例的注意事项:在 0,1,2,3,4... 处索引仅用于演示,实际上 i = 0;开始 for 循环 trolls.get(i++).getX()、trolls.get(i++).getY() 等等。如果你的列表是 10,000,你最终会得到一个 NoSuchElementException

例如,如果你只有 3 个巨魔,一旦你到达第四个 itr.next(),你就会得到一个 NoSuchElementException。因此,您需要将 next() 元素存储在变量中并处理该变量,以便 itr.hasNext();正确返回并且 itr.remove() 也正常工作。

关于java - 暂停线程以防止 ConcurrentModificationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8829370/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com