简体   繁体   English

HashMap并发修改

[英]HashMap Concurrent Modification

I am trying to check the server's entities and iterate trough them each second, and if I find one who is not spawned anymore,it will respawn automatically. 我正在尝试检查服务器的实体,并每秒对其进行遍历,如果我发现不再生成的实体,它将自动重新生成。

The problem occurs when, in my EntitySpawnEvent I remove the old entity from the hashmap and add a new one, this creating a java.util.ConcurrentModificationException . 当在我的EntitySpawnEvent我从哈希图中删除旧实体并添加一个新实体,从而创建java.util.ConcurrentModificationException时,就会发生问题。 Is there any possibility I can least suppress this errors? 有没有可能我至少可以抑制此错误? (Because I am removing an Entity that the "check" already passed through.) (因为我要删除已经通过“检查”的实体。)

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);

You can use iterator for removing entities that you detect for removing. 您可以使用迭代器删除检测到要删除的实体。

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);

I'm not sure whether it's removeHologram() or setEntityRespawn() is removing the entity. 我不确定是removeHologram()还是setEntityRespawn()正在删除实体。 In any case, I would refactor the logic so that you can remove the entity in the for loop itself. 无论如何,我都会重构逻辑,以便您可以在for循环中删除实体。 Although you do have option to pass iterator itself to these methods, and call it.remove() in there. 尽管您确实可以选择将迭代器本身传递给这些方法,然后在其中调用it.remove()。

If you have multiple BukkitRunnable threads running, and they all have access to same HashMap, then it's advisable to use ConcurrentHashMap implementation for CheckAliveEntities. 如果您有多个正在运行的BukkitRunnable线程,并且它们都可以访问相同的HashMap,则建议对CheckAliveEntities使用ConcurrentHashMap实现。 Please see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html 请参阅http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM