3

I executing below code but some times i got java.util.ConcurrentModificationException exception..But some times working fine.please let me know where i did wrong code.Below is my code please check my logic also if there is any better way then let me know.

    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);
    }
Ravi Chothe
  • 180
  • 5
  • 17

2 Answers2

7

This is from the JavaDoc for ConcurrentModificationException:

For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

In your last loop, you sometimes do

user.getSkillsList().add(skillObj);

while iterating using user.getSkillsList().iterator().

Keppil
  • 45,603
  • 8
  • 97
  • 119
  • You mean one thread is iterating the collection and the other thread modifies the list. Am i right? – Keerthivasan Jan 30 '14 at 12:00
  • its the same thread doing the mod and iteration so it would not cause the Exception – user1428716 Jan 30 '14 at 12:00
  • @Octopus: No, the same thread is doing the iteration and modification here. Of course more threads could be running the same method at the same time, but it is not needed to produce this error. – Keppil Jan 30 '14 at 12:03
  • Ok . got it -- Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception. – user1428716 Jan 30 '14 at 12:05
  • @Keppil I couldn't understand it. How can a single thread can modify the list and do the iteration concurrently? i.e. at the same time. I also see that the iterator is created only after the list has been modified. Can you explain a bit to understand? – Keerthivasan Jan 30 '14 at 12:07
  • @Octopus: The code modifies the collection between two calls to `next()`. They belong to the same iteration, hence the error. – Keppil Jan 30 '14 at 12:09
2

ConcurrentModificationExceptions happen when modifying a Collection while iterating it, other than using the Iterator.remove() method.

So, it will be thrown when executing:

user.getSkillsList().add(skillObj);

From the Java Tutorials, The Collection interface :

Note that Iterator.remove is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

Xavi López
  • 27,550
  • 11
  • 97
  • 161
  • Create another `List` and add the elements to it while you iterate. You can process it as suited when the loop ends. – Xavi López Jan 30 '14 at 12:09
  • but that exception got 2nd time.I created another loop and tried.but still got same exception – Ravi Chothe Jan 30 '14 at 12:11
  • The culprit here is _you can't modify a list while iterating over it_. It doesn't matter if it is a different loop, as long as you modify the list you're iterating over. Instead of adding to the same list, you could add to a new one, and when out of the loop, add all elements from the new list to the old one. And then repeat processing of the original list with the new elements (didn't really look into the logics of what you're trying to do; just a quick suggestion). – Xavi López Jan 30 '14 at 12:20