gpt4 book ai didi

java - TryCatch ConcurrentModificationException 捕获 30% 的时间

转载 作者:行者123 更新时间:2023-12-03 21:45:43 25 4
gpt4 key购买 nike

我正在使用迭代器从列表中删除抛射物,如果它超出了我的 JPanel 的边界。在使用迭代器之前它不会工作,但使用迭代器它可以工作,只要我将该方法放入 ConcurrentModificationException 的 try-catch 中。代码现在可以运行,并成功地从列表中删除了射弹,但大约 30% 的时间,捕获命中并导致我的程序卡顿。我不知道为什么它只是偶尔捕获,但在有限的时间内我的教授能够查看它,他认为这可能是一个同步问题。

这是运行我的程序的循环:

private void executeGameLoop() 
{

long nextFrameStart = System.nanoTime();
while(panel.getRunning())
{
do
{
panel.repaint();
nextFrameStart += FRAME_PERIOD;
} while(nextFrameStart < System.nanoTime());

long remaining = nextFrameStart - System.nanoTime();
panel.update();

if (remaining > 0)
{
try
{
Thread.sleep(remaining / 1000000);
}
catch(Throwable e)
{
System.out.println(e.getMessage());
}
}
}
}

这由 panel.update 中的循环调用。它现在负责更新射弹:

public void update()
{
randX = (int)((Math.random() * getWidth()) - (int)(Math.random() * getWidth()));
randY = (int)((Math.random() * getHeight()) - (int)(Math.random() * getHeight()));

int sizeX;
int sizeY;

try
{
Iterator<Projectile> it = shots.iterator();
for(Projectile a : shots)
{
if(!a.equals(null))
{
sizeX = a.getDisplayX();
sizeY = a.getDisplayX();

if((!checkCoords((int)a.getX(), (int)a.getY(), sizeX, sizeY)) && a.hasTarget())
{
a = null;
if(it.next().equals(null));
it.remove();
}

else if(a.hasTarget())
{
a.update();
}
}
}
}
catch (ConcurrentModificationException e){ System.out.println(e.getMessage() + " Catch"); }
}

这最后两种方法是我创建射弹的机制:

private void createProjectile(int x, int y)
{
total++;
if(shots.size() < shotCount)
{
Projectile temp = new Projectile(randX, randY);
temp.setTarget((x + temp.getSprite().getDisplayImg().getWidth() / 8),
(y - temp.getSprite().getDisplayImg().getHeight() / 8));
temp.setHasTarget(true);
shots.add(temp);
msg("Target: (" + x + ", " + y + ")");
}
}

@Override
public void mouseClicked(MouseEvent e)
{
createProjectile(e.getX(), e.getY());
}

任何关于为什么会发生这种情况或如何纠正它的见解将不胜感激。

最佳答案

您在 for 循环中有一个打开的 Iterator(加上额外的 Iterator it),并且您在 中添加值>创建射弹。您需要在 shots 上使两个 block 同步,或者(我的建议)制作 shots 的副本以从以下位置进行绘图:

List<Projectile> shotsToPaint;
synchronized(shots) { shotsToPaint = [`ImmutableList`][1].copyOf(shots); }

并在 createProjectile 中应用适当的同步。根据它对性能的敏感程度,您可以在 shots 上同步整个方法或在 shots 上同步,检查大小,创建新的 Projectile 在一个未同步的 block 中,然后同步以重新检查列表大小并添加。

关于java - TryCatch ConcurrentModificationException 捕获 30% 的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18752320/

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