2010-05-13 7 views
-1

j'écrire du code ci-dessous, mais quand ce lancez-le générer ConcurrentModificationExceptionConcurrentModificationException hashmap en java

if(attendancePolicy.getType().equals(AttendanceConstants.EMPLOYEE_ATTENDANCE_POLICY)) { 
    synchronized(attendancePolicy.getListEmployee()) { 
     for(EmployeeAttendancePolicy employeeAttendancePolicy : attendancePolicy.getListEmployee()) { 
      employeeInfo = employeeInfoSessionBeanLocal.findEmployeeInfoEntityByEmployeeInfoId( 
        employeeAttendancePolicy.getEmployeeId()); 

      if(employeeInfo != null) { 
       employeeAttendancePolicy.setEmpName( 
         employeeInfo.getFirstName() + " " 
         + employeeInfo.getMiddleName() + " " 
         + employeeInfo.getLastName()); 

       company = companySessionBeanLocal.findCompanyById(employeeInfo.getCompanyId()); 
       employeeAttendancePolicy.setCompanyName(company.getName()); 

       department = departmentSessionBeanLocal.findDepartmentEntityByDepartmentId( 
         employeeInfo.getDepartmentId()); 
       employeeAttendancePolicy.setDepartmentName(department.getName()); 
      } 
      else { 
       attendancePolicy.getListEmployee().remove(employeeAttendancePolicy); 
      } 
     } 
    } 
} 
+1

Copie possible de [Itérer à travers une collection, en évitant ConcurrentModificationException lors de la suppression en boucle] (http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re) – Raedwald

Répondre

1

Le ConcurrentModificationException est causé par le fait que vous utilisez un Iterator sur une List, et vous êtes en train de modifier ensuite que List.

Voir la Iterator Java doc la page - http://java.sun.com/j2se/1.4.2/docs/api/java/util/Iterator.html, vous pouvez utiliser la méthode remove du Iterator pour éviter ceci:

Enlève de la collection sous-jacente le dernier élément renvoyé par la iterator (opération facultative) . Cette méthode ne peut être appelée qu'une seule fois par appel suivant. Le comportement d'un itérateur n'est pas spécifié si la collection sous-jacente est modifiée tandis que l'itération est en cours en autrement qu'en appelant cette méthode .

Réécrivez votre code à ceci:

if(attendancePolicy.getType().equals(AttendanceConstants.EMPLOYEE_ATTENDANCE_POLICY)) { 
    synchronized(attendancePolicy.getListEmployee()) { 

     // Explicitly create the Iterator and loop condition 
     for(Iterator<EmployeeAttendancePolicy> it = 
attendancePolicy.getListEmployee().iterator(); it.hasNext();) { 

      // Explicitly declare the looping variable 
      EmployeeAttendancePolicy employeeAttendancePolicy = it.next(); 

      employeeInfo = employeeInfoSessionBeanLocal.findEmployeeInfoEntityByEmployeeInfoId( 
        employeeAttendancePolicy.getEmployeeId()); 

      if(employeeInfo != null) { 
       employeeAttendancePolicy.setEmpName( 
         employeeInfo.getFirstName() + " " 
         + employeeInfo.getMiddleName() + " " 
         + employeeInfo.getLastName()); 

       company = companySessionBeanLocal.findCompanyById(employeeInfo.getCompanyId()); 
       employeeAttendancePolicy.setCompanyName(company.getName()); 

       department = departmentSessionBeanLocal.findDepartmentEntityByDepartmentId( 
         employeeInfo.getDepartmentId()); 
       employeeAttendancePolicy.setDepartmentName(department.getName()); 
      } 
      else { 

       // Use the Iterator's remove method to safely remove 
       // thus avoiding the ConcurrentModificationException 
       it.remove(); 

      } 
     } 
    } 
} 
2

Vous supprimons employeeAttendancePolicy de l'employé de liste à partir d'une boucle for qui est itérez la collection des employés de la liste. C'est l'opération "simultanée" qui a provoqué l'exception.

Si vous souhaitez supprimer quelque chose à l'intérieur d'une boucle, vous devez revenir à une boucle d'itérateur "normale" (pas la boucle "améliorée" pour ci-dessus). Quelque chose comme ça peut-être:

Iterator<EmployeeAttendancePolicy> iter = attendancePolicy.getListEmployee(); 
while (iter.hasNext()) 
{ 
    EmployeeAttendancePolicy employeeAttendancePolicy = iter.next(); 

    //... somewhere in here when you decide to remove 
    iter.remove(); 
} 
0

Vous supprimez un élément de la liste que vous itérez. Pour résoudre ce problème, vous pouvez ajouter l'élément à supprimer dans une nouvelle collection, puis, une fois la première boucle terminée, supprimer ces éléments de la liste.

par exemple. quelque chose comme

 synchronized (attendancePolicy.getListEmployee()) { 
      Set toRemove = new HashSet(); 

      for(EmployeeAttendancePolicy employeeAttendancePolicy : attendancePolicy.getListEmployee()){ 

       employeeInfo=employeeInfoSessionBeanLocal.findEmployeeInfoEntityByEmployeeInfoId(employeeAttendancePolicy.getEmployeeId()); 

       if(employeeInfo!=null){ 
        ... 
       }else{ 
        toRemove.add(employeeAttendancePolicy); 
       } 

      } 
      attendancePolicy.getListEmployee().removeAll(toRemove); 
     } 
0

Jetez un oeil à ConcurrentHashMap et CopyOnWriteArrayList. Ces collections sont conçues pour être utilisées lorsque plusieurs threads travaillent sur des collections.

Questions connexes