【问题标题】:Exception in thread "main" java.util.ConcurrentModificationException (Head first java book example)线程“main”java.util.ConcurrentModificationException 中的异常(Head first java book example)
【发布时间】:2015-04-16 19:34:28
【问题描述】:

我尝试运行 Head first java book - second edition(第 152 页)中的示例。它是一个游戏拼图。它以网格中的 Dotcoms(string) 为目标,将它们击沉。但是当我尝试运行这个谜题时,我得到了一个 Java.util.concurrentModificationException 错误。当我试图在网格中沉没最后一个 dotCom(String) 时,我才得到这个错误。假设我在网格中有三个字符串,如下图所示。因此,当我开始提供输入时,我能够删除(命中)前两个字符串(因为它们在 arrayList 中添加)但是当我尝试删除最后一个字符串(在 Arraylist 中最后添加的字符串)时,得到 concurrentmodificationException 错误。下面给出了示例代码和控制台日志。
那么为什么我会收到此错误以及如何删除此错误。

class DotComBust{

    private GameHelper helper = new GameHelper();
    private ArrayList<DotCom> dotComList = new ArrayList<DotCom>();
    private int numofguesses=0;

    private void setUpGame(){
        DotCom one = new DotCom();
        one.setNames("Pets.com");
        DotCom two = new DotCom();
        two.setNames("eToys.com");
        DotCom three = new DotCom();
        three.setNames("Go2.com");
        dotComList.add(one);
        dotComList.add(two);
        dotComList.add(three);

        System.out.println("your goal is sunk three dot coms");
        System.out.println("Pets.com, eToys.com, Go2.com");
        System.out.println("Try to sink them all in fewest number of guesses");

        for(DotCom dotComToSet : dotComList){
            ArrayList<String> newLocation = helper.placeDotCom(3);
            dotComToSet.setLocationCells(newLocation);
        }

    }

        private void startPlaying(){
            while(!dotComList.isEmpty()){
                String userGuess = helper.getUserInput("Enter a guess");
                checkUserGuess(userGuess);
            }

            finishGame();
        }

        private void checkUserGuess(String userGuess){
            numofguesses++;
            String result = "miss";
            for(DotCom dotComToTest : dotComList){
                result = dotComToTest.checkYourself(userGuess);

                if(result.equals("hit")){
                    break;
                }
                if(result.equals("kill")){
                    dotComList.remove(dotComToTest);
                }
            }
        System.out.println(result);
        }


        private void finishGame(){
            System.out.println("All the dotcoms are dead your stock is worthless");
            if(numofguesses<=18){
                System.out.println("It only took you" + numofguesses + "guesses");
                System.out.println("You got out before your option sank");

            }else{
                System.out.println("Took you long enough" + numofguesses + "guesses");
                System.out.println("Fish are dancing with your option");
            }
        }

        public static void main(String[] args) {
            DotComBust game = new DotComBust();
            game.setUpGame();
            game.startPlaying();
        }

}

错误

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at DotComBust.checkUserGuess(DotComBust.java:77)
at DotComBust.startPlaying(DotComBust.java:68)
at DotComBust.main(DotComBust.java:106)

【问题讨论】:

    标签: java android java.util.concurrent concurrentmodification


    【解决方案1】:

    我假设您可能同时运行另一个绘图线程?

    在这种情况下,使用List 的线程安全实现,称为CopyOnWriteArrayList

    private ArrayList&lt;DotCom&gt; dotComList = new CopyOnWriteArrayList&lt;DotCom&gt;();

    【讨论】:

      【解决方案2】:

      因为当你循环一个集合时

       while(!dotComList.isEmpty()){
                  String userGuess = helper.getUserInput("Enter a guess");
                  checkUserGuess(userGuess);
       }
      

      您不允许修改列表的内容,但在您的方法 checkUserGuess 中您试图从列表中删除元素

      if(result.equals("kill")){
                          dotComList.remove(dotComToTest);
      }
      

      这是导致 ConcurrentModificationException 的原因

      【讨论】:

      • 好的,为什么这不适用,为什么我以 B1、D1、C1 等非串行方式输入,仅当我尝试以 B1、B2、B3 等串行方式输入时才会出现错误。为什么会这样?
      • 正如你解释的原因,我的回答已经解释了解决方案以及如何处理事情。在不理解的情况下投反对票显然是不成熟的。
      • @Android 开发人员,可能只有当您输入系列值时,您的结果才等于 kill。调试它并找出答案。
      猜你喜欢
      • 2014-12-12
      • 1970-01-01
      • 2013-05-06
      • 2013-11-21
      • 2012-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多