Question

I have the following code

public void saveProjects(List<Project> proj) throws DatabaseException {
    for (Project listItems: proj) { // error here

        insertProjects(listItems);
    }
}

private void insertProjects(Project prj) throws DatabaseException {
    commitObjects(prj);
}

When I am executing the above, I am getting the following exception at for (Project listItems: proj) {

java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449) at java.util.AbstractList$Itr.next(AbstractList.java:420)

How can I resolve this issue with usage of next or with iterator?

Edit 1

Code snippet where I am calling saveProjects

projectList.add(proj);
  for (Project persist: projectList) {
       persist.setProjectId("K7890");
       persist.setName(fileName);

          myDAO.saveProjects(projectList);

     }
  projectList.clear();
Was it helpful?

Solution

From code

for (Project persist: projectList) { 
     persist.setProjectId("K7890");
     persist.setName(fileName);

      myDAO.saveProjects(projectList); 
 }

projectList.clear(); // <-- clear might cause to this Exception

Reference

Why do you get a ConcurrentModificationException when using an iterator?

The java.util Collection classes are fail-fast, which means that if one thread changes a collection while another thread is traversing it through with an iterator the iterator.hasNext() or iterator.next() call will throw ConcurrentModificationException.

Even the synchronized collection wrapper classes SynchronizedMap and SynchronizedList are only conditionally thread-safe, which means all individual operations are thread-safe but compound operations where flow of control depends on the results of previous operations may be subject to threading issues. (List myList = Collections.synchronizedList (myList) ! It may not work here)

Solutions for multi-thread access situation

Solution 1: You can convert your list to an array with list.toArray() and iterate on the array. This approach is not recommended if the list is large.

Solution 2: You can lock the entire list while iterating by wrapping your code within a synchronized block. This approach adversely affects scalability of your application if it is highly concurrent.

Solution 3: You can use the ConcurrentHashMap and CopyOnWriteArrayList classes, which provide much better scalability and the iterator returned by ConcurrentHashMap.iterator() will not throw ConcurrentModificationException while preserving thread-safety.

Solution for single-thread access situation

Use:

it.remove();

It removes the current object via the Iterator it which has a reference to your underlying collection list.

Avoid:

list.remove(myObject);

OTHER TIPS

Looks strange, my guess is that you modify the list (List<Project> proj) in another thread while iterating over it?

Because you do not alter the list in any way in the code you have given us.

You can try calling the saveProjects method with a copy of the proj list.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top