HashMap并发修改

时间:2015-08-15 01:11:25

标签: java hashmap

我正在尝试检查服务器的实体并每秒迭代它们,如果我找到一个不再生成的实体,它将自动重新生成。

当我在EntitySpawnEvent中从散列映射中删除旧实体并添加新实体时,会出现问题,这会创建java.util.ConcurrentModificationException。有没有可能我最不能抑制这个错误? (因为我删除了一个实体,"检查"已经通过了。)

new BukkitRunnable() {
        public void run() {
            for(Entity e : CheckAliveEntities.keySet()) {
                if(!(e.isValid())) {
                        if(!(e instanceof Player)) {
                            System.out.println("DA");
                            x.removeHologram(e);
                            y.setEntityRespawn(e);
                            break;
                        }
                }
            }
        }       
    }.runTaskTimer(this, 5, 5);

1 个答案:

答案 0 :(得分:0)

您可以使用迭代器删除检测到要删除的实体。

new BukkitRunnable() {
    public void run() {
        for(Iterator<Entity> it = CheckAliveEntities.keySet().iterator(); it.hasNext();) {
            Entity e = it.next();
            if ( !e.isValid() && !(e instanceof Player) ) {
                        System.out.println("DA");
                        x.removeHologram(e); // needs refactoring
                        it.remove();
                        y.setEntityRespawn(e); // needs refactoring
                        break;
                    }
            }
        }
    }       
}.runTaskTimer(this, 5, 5);

我不确定removeHologram()或setEntityRespawn()是否正在删除实体。在任何情况下,我都会重构逻辑,以便您可以删除for循环中的实体。虽然你可以选择将迭代器本身传递给这些方法,并在那里调用it.remove()。

如果您运行多个BukkitRunnable线程,并且它们都可以访问相同的HashMap,那么建议对CheckAliveEntities使用ConcurrentHashMap实现。请参阅http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html