我正在和计时器搞混,以了解我想到的新游戏。目前,我有使用计时器淡入和淡出的正方形,当它们完全淡出时,它们将从"活动磁贴列表中删除。我有另一个计时器,而淡入淡出计时器也可能正在运行,它在随机位置产生方块,每个都有淡入淡出。这一切看起来都很漂亮,但在后端出现问题。
程序抛出ConcurrentModificationException。我对这些的了解非常有限,但我知道在迭代对象和同时更改对象时会发生这种情况。
这可能发生在我的程序中,可能是两个滴答声同时相遇,它会抛出此异常,但我不知道。
在我脑海中,这似乎是唯一的方法,因为我真的只知道计时器的一种标准方法,并且对此没有多少经验。我想知道是否有更好的方法不会导致这个并发异常,和/或解释为什么会发生这种情况。
谢谢!
以下是一些相关代码: (我使用的是Android图形库,但它并不适用于此)
Game.java:
public Game(Context context) {
super(context);
metrics = context.getResources().getDisplayMetrics();
SCREEN_WIDTH = metrics.widthPixels;
SCREEN_HEIGHT = metrics.heightPixels;
spawner = new Spawner();
}
@Override
protected void onDraw(Canvas canvas) {
for(Tile tile : spawner.activeTiles) {
//System.out.println("Tile Color: " + tile.getColor());
canvas.drawRect(tile, tile.getColor());
}
try { Thread.sleep(10); }
catch (InterruptedException e) {}
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent e) {
System.out.println(spawner.activeTiles);
float x = e.getX();
float y = e.getY();
for(Tile tile : spawner.activeTiles) {
if(tile.contains(x, y) && tile.equals(spawner.activeTiles.get(0))) {
tile.setBroken(true);
spawner.activeTiles.remove(tile);
}
}
return true;
}
Tile.java:
public Tile(int lifetime) {
super();
this.lifetime = lifetime;
TILE_WIDTH = (int) Game.SCREEN_WIDTH / 10;
TILE_HEIGHT = (int) Game.SCREEN_HEIGHT / 15;
tileColor = new Paint();
tileColor.setColor(Color.argb(0, 255, 0, 0));
placeTile();
}
private void placeTile() {
float screenWidth = Game.SCREEN_WIDTH;
float screenHeight = Game.SCREEN_HEIGHT;
Random random = new Random();
top = random.nextInt((int) screenHeight - (TILE_HEIGHT * 2)) + 10;
left = random.nextInt((int) screenWidth - (TILE_WIDTH * 2)) + 10;
bottom = top + TILE_HEIGHT;
right = left + TILE_WIDTH;
fadeIn(5);
}
private void fadeIn(final int speed) {
if(tileColor != null) {
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
int alpha = tileColor.getAlpha();
if(alpha < 255) {
if(alpha + 5 > 255) tileColor.setAlpha(255);
else tileColor.setAlpha(alpha + 5);
} else {
timer.cancel();
fadeOut(speed);
}
}
}, 50, speed);
}
}
private void fadeOut(int speed) {
if(tileColor != null) {
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
int alpha = tileColor.getAlpha();
if(alpha > 0 && !broken) {
if(alpha - 5 < 0) tileColor.setAlpha(0);
else tileColor.setAlpha(alpha - 5);
} else {
failed = true;
timer.cancel();
}
}
}, lifetime, speed);
}
}
Spawner.java:
public List<Tile> activeTiles = new ArrayList<Tile>();
public long tileDelay = 500;
public Spawner() {
start();
}
private void start() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
removeFailedTiles();
activeTiles.add(new Tile(1000));
}
}, 0, tileDelay);
}
private void removeFailedTiles() {
for(Tile tile : activeTiles) {
if(tile.isFailed()) {
activeTiles.remove(tile);
}
}
}
答案 0 :(得分:3)
使用Iterator
并致电remove()
:
Iterator<Tile > iter = activeTiles.iterator();
while (iter.hasNext()) {
Tile tile= iter.next();
if(tile.isFailed())
iter.remove();
}
This链接将帮助您了解并发修改例外。