试图避免并发修改例外

时间:2016-07-14 05:57:37

标签: java hashmap

我正在尝试避免并发修改例外。我将实体HashMap循环到tick()每个实体。玩家实体在WASD输入的屏幕上移动,并在玩家向右移动时测试addNewEntity()方法我调用GameState.addNewEntity(new Explosion(true, this.x, this.y));。几个爆炸出现在玩家身上,然后我收到一个错误。 Player类扩展了扩展Entity的Creature。爆炸扩展了实体类。

此代码来自我的GameState类:

private static HashMap<Integer, Entity> entities = new HashMap<Integer, Entity>();
private static HashMap<Integer, Entity> newEntities = new HashMap<Integer, Entity>();

player = new Player(game, true, 100, 100);
entities.put(0, player);

我的tick()方法:

public void tick() {
    // add new elements from newEntities to entities, deleting from newEntities
    for (Entry<Integer, Entity> entry : newEntities.entrySet()) { 
        entities.put(entities.size(), entry.getValue());
        newEntities.remove(entry.getValue());
    }

    System.out.println(entities.size());

    // tick the updated entities HashMap
    for (Entry<Integer, Entity> entry : entities.entrySet()) { 
        entry.getValue().tick();

        // remove dead entities
        if (!entry.getValue().isAlive) {
             entities.remove(entry.getKey());
        }
    }
}

我的addNewEntity方法:

public static void addNewEntity(Entity e) {
    // add a new element to newEntities. 
    newEntities.put(newEntities.size(), e);
}

我的渲染方法:

public void render(Graphics g) {
    for (Entry<Integer, Entity> entry : entities.entrySet()) { 
        entry.getValue().render(g);
    }
}

我试图通过添加到newEntities HashMap而不是添加到实体HashMap来避免并发修改异常。在我的tick方法中,我遍历newEntities HashMap并将那里存在的每个项目添加到实体,依次删除每个项目。只有在那之后,我才会遍历实体HashMap。

如果我在迭代它时修改地图怎么可能?

1 个答案:

答案 0 :(得分:1)

不允许直接从Map中删除条目,同时使用增强的for循环迭代它。相反,使用显式迭代器进行迭代,使用迭代器的remove()方法。

Iterator<Map.Entry<Integer, Entity>> iter = newEntities.entrySet().iterator();
while (iter.hasNext()) { 
    Map.Entry<Integer, Entity> entry = iter.next();
    entities.put(entities.size(), entry.getValue());
    iter.remove();
}

对第二个循环执行相同的操作。