【问题标题】:Some times java.util.ConcurrentModificationException thrown有时会抛出 java.util.ConcurrentModificationException
【发布时间】:2014-01-30 11:49:52
【问题描述】:

我执行下面的代码,但有时我得到 java.util.ConcurrentModificationException 异常..但有时工作正常。请让我知道我在哪里做错了代码。下面是我的代码,如果有更好的,请检查我的逻辑那么请告诉我。

    public  String saveSkills(HttpServletRequest request,@RequestParam String skills,@RequestParam String Email) throws IOException
    {

        Domain domain1 = (Domain)request.getSession().getAttribute("Domain");
        Long domanId =domain1.getDomainId();
        System.out.println(skills);
        String[] skillsParts = skills.split(",");
        UserProfile user = userProfileManager.getUserByEmail(domain1.getPrimary_Domain_Id(), Email);
        if(user.getSkillsList().size()>0){
            Iterator it = user.getSkillsList().iterator();
            while (it.hasNext())
            {
                Skills skillsitereator = (Skills) it.next();
                int count=0;

                for(int i =0;i<skillsParts.length;i++){

                    if((skillsParts)[i].equals(skillsitereator.getSkillName())){

                        break;

                    }else{

                        count++;
                    }
                }
                if(count == skillsParts.length){
                    it.remove();
                    userProfileManager.update(user);
                }
            }
        }else{

            for(int i =0;i<skillsParts.length;i++){

                Skills skillObj = new Skills();
                skillObj.setSkillName(skillsParts[i]);
                user.getSkillsList().add(skillObj);

            }
            userProfileManager.update(user);
        }
        skillsParts = skills.split(",");
        System.out.println(skillsParts);
        ArrayList<Integer> values =new ArrayList<Integer>();
        for(int i =0;i<skillsParts.length;i++){
            Iterator it = user.getSkillsList().iterator();
            while (it.hasNext())
            {
                Skills skillsitereator = (Skills) it.next();
                if((skillsParts)[i].trim().equals(skillsitereator.getSkillName().trim())){
                    break;
                }
                else{

                    Skills skillObj = new Skills();
                    skillObj.setSkillName(skillsParts[i]);
                    user.getSkillsList().add(skillObj);
                    userProfileManager.update(user);
                }
            }
        }
        Gson gson = new Gson();
        return gson.toJson(user);
    }

【问题讨论】:

  • 堆栈跟踪会有所帮助

标签: java spring exception concurrency


【解决方案1】:

这是来自ConcurrentModificationException 的 JavaDoc:

例如,如果一个线程在使用 fail-fast 迭代器对集合进行迭代时直接修改了一个集合,则迭代器将抛出此异常。

在你的最后一个循环中,你有时会这样做

user.getSkillsList().add(skillObj);

在使用 user.getSkillsList().iterator() 进行迭代时。

【讨论】:

  • 您的意思是一个线程正在迭代集合,而另一个线程修改列表。我说的对吗?
  • 它是同一个线程做mod和迭代,所以它不会导致异常
  • @NiksTyagi 谢谢。
  • @Octopus:不,同一个线程在这里做迭代和修改。当然更多的线程可以同时运行同一个方法,但不需要产生这个错误。
  • 好的。明白了——请注意,此异常并不总是表明对象已被不同的线程同时修改。如果单个线程发出一系列违反对象约定的方法调用,则该对象可能会抛出此异常。例如,如果线程在使用快速失败迭代器迭代集合时直接修改了集合,则迭代器将抛出此异常。
【解决方案2】:

ConcurrentModificationExceptions 在迭代 Collection 时发生,而不是使用 Iterator.remove() 方法。

所以,执行的时候会抛出:

user.getSkillsList().add(skillObj);

来自 Java 教程,The Collection interface

请注意,Iterator.remove 是在迭代期间修改集合的唯一安全方法;如果在迭代过程中以任何其他方式修改了底层集合,则行为未指定。

【讨论】:

  • 创建另一个 List 并在迭代时向其中添加元素。您可以在循环结束时对其进行处理。
  • 但该异常发生了第二次。我创建了另一个循环并尝试了。但仍然遇到相同的异常
  • 这里的罪魁祸首是在迭代列表时不能修改列表。只要你修改你正在迭代的列表,它是否是一个不同的循环并不重要。您可以添加到一个新列表,而不是添加到同一个列表中,然后在退出循环时,将新列表中的所有元素添加到旧列表中。然后用新元素重复处理原始列表(并没有真正研究你想要做什么的逻辑;只是一个快速的建议)。
猜你喜欢
  • 2014-01-13
  • 1970-01-01
  • 2018-10-02
  • 2012-07-28
  • 1970-01-01
  • 2014-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多