LinkedHashMap ConcurrentModificationException错误

时间:2013-06-10 04:05:49

标签: java exception concurrenthashmap linkedhashmap concurrentmodification

在我的MUDRPG程序中,目前有两个线程(如果我没弄错的话,我没有编写引擎)。一个线程纯粹是图形化的,显示所有Gui个对象,另一个线程处理所有计算。第二个线程是处理战斗的线程。在我的战斗代码中,我正在检查是否存在hitsplat gui,但是,在几次成功调用该函数(每次都有一个不同的数字)之后,我遇到了ConcurrentModificationException。这似乎是因为在这场战斗试图检查是否存在hitsplats的同时,图形线程正试图从LinkedHashMap显示事物。有人可以告诉我,从LinkedHashMap阅读的正确方法是避免此问题,还是需要使用ConcurrentHashMap?我的理解是LinkedHashMap被使用是因为它可以处理顺序,我不太确定ConcurrentHashMap是否也适用。

访问计算线程上的LinkedHashMap的代码:

private boolean checkHitsplats(){
    System.out.println("I get called)");
    while (true) {
        try {
            if (OneQuest.getInstance().getTickThread().getGuis()
                    .get("HitsplatPlayer") == null
                    && OneQuest.getInstance().getTickThread().getGuis()
                            .get("HitsplatMonster1") == null
                    && OneQuest.getInstance().getTickThread().getGuis()
                            .get("HitsplatMonster2") == null
                    && OneQuest.getInstance().getTickThread().getGuis()
                            .get("HitsplatMonster3") == null) {
                return false; // return false if none exist
            } else
                return true; // return true of any hitsplats exist
        } catch (ConcurrentModificationException e) {
            System.out.println("modification error");
        }
    }
}

循环遍历linkedHashMap以显示图形项的代码片段,其中guis是LinkedHashMap,其中添加了所有图形对象。

private void tick() {
    synchronized (guis) {
        Iterator<Gui> iter = guis.values().iterator();
        while (iter.hasNext()) {
            Gui gui = iter.next();
            if (gui.isShowing()) {
                gui.render(window);
            }
        }
    }
    if (guiConsole.isShowing()) {
        guiConsole.render(window);
    }
}

编辑:checkHitsplats的第2版,由善良的人建议。

private boolean checkHitsplats(){
    Object[] guis = OneQuest.getInstance().getTickThread().getGuis().values().toArray();
    System.out.println("I get called)");

    while (true) {
        try {
            for (int i = 0; i < guis.length; i++) {
                if (((Gui) guis[i]).getGuiName() == "HitsplatPlayer"
                        || ((Gui) guis[i]).getGuiName() == "HitsplatMonster1"
                        || ((Gui) guis[i]).getGuiName() == "HitsplatMonster2"
                        || ((Gui) guis[i]).getGuiName() == "HitsplatMonster3")
                    return true;
            }
            return false;
        } catch (Exception e) {
        }
    }

1 个答案:

答案 0 :(得分:2)

ConcurrentHashMap在迭代时不会抛出ConcurrentModificationException,但正如您所指出的那样,它不会跟踪关键顺序。另一种选择是迭代LinkedHashMap#values.toArray()LinkedHashMap#entrySet.toArray() - toArray将复制该集合,因此迭代它返回的数组不会抛出ConcurrentModificationException