简体   繁体   English

java中的并发修改异常哈希图

[英]concurrentmodificationexception hashmap in java

I write following code but when this run it generate concurrentmodificationexception 我编写以下代码,但运行时会生成并发修改异常

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 );
            }
        }
    }
}

You're removing employeeAttendancePolicy from the list employee from within a for-loop that is iterating over the list employee collection. 您正在迭代列表雇员集合的for循环中,从列表雇员中删除employeeAttendancePolicy That is the "concurrent" operation that has caused the exception. 这是导致异常的“并发”操作。

If you want to remove something from inside a loop, you need to revert to a "regular" iterator loop (not the "enhanced" for loop above). 如果要从循环内部删除某些内容,则需要恢复为“常规”迭代器循环(而不是上面的“增强”的for循环)。 Something like this perhaps: 大概是这样的:

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

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

The ConcurrentModificationException is caused by the fact that you are using an Iterator over a List , and you are then modifying that List . ConcurrentModificationException是由以下事实引起的:您在List上使用了Iterator ,然后又在修改该List

See the Iterator Java doc page - http://java.sun.com/j2se/1.4.2/docs/api/java/util/Iterator.html , you could use the remove method of the Iterator to avoid this: 请参阅Iterator Java文档页面-http://java.sun.com/j2se/1.4.2/docs/api/java/util/Iterator.html ,可以使用Iteratorremove方法来避免这种情况:

Removes from the underlying collection the last element returned by the iterator (optional operation). 从基础集合中移除迭代器返回的最后一个元素(可选操作)。 This method can be called only once per call to next. 每次调用next只能调用一次此方法。 The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method. 如果在迭代进行过程中以其他方式(而不是通过调用此方法)修改了基础集合,则未指定迭代器的行为。

Rewrite your code to this: 将代码重写为此:

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();

            }
        }
    }
}

You are removing an item from the list you are iterating over. 您正在从要迭代的列表中删除项目。

One way to resolve this is to add the item to remove to a new collection, and then, when you have completed the first loop, remove those items from the list. 解决此问题的一种方法是将要删除的项目添加到新集合中,然后在完成第一个循环后,从列表中删除那些项目。

eg something like 例如类似

        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);
        }

Take a look at ConcurrentHashMap and CopyOnWriteArrayList. 看一下ConcurrentHashMap和CopyOnWriteArrayList。 These collections are designed to be used when multiple thread are working on collections. 这些集合被设计为在多个线程在集合上工作时使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java HashMap中的ConcurrentModificationException程序 - ConcurrentModificationException Program in java HashMap HashMap java.util.ConcurrentModificationException - HashMap java.util.ConcurrentModificationException java.util.ConcurrentModificationException:对哈希图的并发访问 - java.util.ConcurrentModificationException: concurrent access to hashmap 访问hashmap时出现java.util.ConcurrentModificationException - java.util.ConcurrentModificationException while accessing hashmap HashMap中的ConcurrentModificationException - ConcurrentModificationException in HashMap 可以更改HashMap的值的成员导致java.util.ConcurrentModificationException - Can changing members of values of HashMap cause java.util.ConcurrentModificationException 在将嵌套哈希图写入文件并在Java中删除元素时发生ConcurrentModificationException错误 - ConcurrentModificationException error while writing nested hashmap to a file and removing element in Java HashMap迭代/删除获取java.util.ConcurrentModificationException - HashMap iteration/removal getting java.util.ConcurrentModificationException 从HashMap中删除元素时发生异常java.util.ConcurrentModificationException - Exception when removing element from HashMap java.util.ConcurrentModificationException 从哈希图中删除元素时出现 java.util.ConcurrentModificationException - java.util.ConcurrentModificationException when removing elements from a hashmap
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM