这是从List中删除元素的一种线程安全的方法吗?

时间:2017-11-12 05:04:06

标签: java android list single-threaded

所以我正在制作Android游戏,我有一个名为ParticleEmitter的单例类,它具有向CopyOnWriteArrayList添加粒子的功能。添加到列表中的是抽象Particle,它可以是Laser粒子或Meteor粒子。我还有一个MainThread类作为游戏引擎,它处理帧的绘制和更新。

所以这个ParticleEmitter类有一个update()函数来处理列表中所有粒子的更新。但它的作用是告诉粒子什么时候会离屏,所以可以从列表中删除它们。 update()函数在遍历所有粒子的过程中,也可以调用checkCollisions(Particle laser)函数来测试激光参数,看它是否与任何一个流星相撞,所以它们都可以从列表中删除。

private Particle checkCollisions(Particle laser) {

    Iterator<Particle> iter = particles.iterator();
    Particle p;
    while (iter.hasNext()) { // looping through all particles
        p = iter.next();
        if (p instanceof Meteor) { // if particle is a meteor, then see if it collides with the passed in laser
            if (p.intersect(laser)) {
                setChanged();
                notifyObservers(GameController.Event.METEOR_DESTROYED);
                return p;
            }
        }
    }

    return null;

}

public void update(int screenWidth, int screenHeight) {

    // function called by game loop (many times a second)

    List<Particle> particlesToRemove = new LinkedList<>();

    int meteors = 0;

    Iterator<Particle> iter = particles.iterator();
    Particle p;
    while (iter.hasNext()) {
        p = iter.next();
        p.update();
        if (p instanceof Laser) {
            Particle m = checkCollisions(p); // returns the collided with meteor if there was a collision, null if not
            if (m != null) {
                particlesToRemove.add(p);
                particlesToRemove.add(m);
            } else if (p.offscreen(screenWidth, screenHeight)) { // no collision with any meteors... still need to check if offscreen
                particlesToRemove.add(p);
            }
        } else {
            meteors++;
            if (p.offscreen(screenWidth, screenHeight)) { // if meteor went off screen, it meant it hit the earth, so need to alert GameController
                setChanged();
                notifyObservers(GameController.Event.METEOR_HIT_EARTH);
                particlesToRemove.add(p);
            }
        }
    }

    particles.removeAll(particlesToRemove);

    if (meteors == 0) {
        setChanged();
        notifyObservers(GameController.Event.NO_METEORS_ON_SCREEN);
    }

}

这段代码是单线程安全吗?我已经测试了一些它似乎工作得很好。我只是想确保我不会遇到任何例外(在此之前我已尝试过很多解决方案;只是想确保我偶然发现了正确的解决方案)。如果你能想出一个更好的方法来实现我在这里所做的事情,我也会感激:)。感谢。

0 个答案:

没有答案