【问题标题】:ConcurrentModificationException In a Java BOJava BO 中的 ConcurrentModificationException
【发布时间】:2013-01-21 22:49:18
【问题描述】:

我在这段代码中遇到了 java.util.ConcurrentModificationException,似乎无法理解原因或修复它。

在 BO 中我有这个(权限是 BO 内的数组列表)

public void setPrivilegename(String privilegename) {
    this.privileges.add(privilegename); 
}

List<PrivilegeObjectBO> arraylist = new ArrayList<PrivilegeObjectBO>();if (rs != null)              {
    while (rs.next()) {        
        for (BO bo : arraylist) {
            if (bo.getRolepkey()==rs.getInt("ROLE_PKEY")) {                         
                bo.setPrivilegename(rs.getString("SP.NAME"));

            }else{
                BO newobj = new BO();
                newobj.setRolepriviledgepkey(rs.getInt("PRIVILEGE_PKEY"));
                newobj.setProticolpkey(protocol);                
                newobj.setPrivilegename(rs.getString("SP.NAME"));
                newobj.setRolepkey(rs.getInt("SRP.ROLE_PKEY"));
                arraylist.add(newobj);
            }
        }
    }
}

【问题讨论】:

    标签: java exception


    【解决方案1】:

    也许你可以看看Collections.synchronizedList(List&lt;?&gt;)静态方法。 它应该从给定的 List 对象中返回一个线程安全的 List,并且您不应再收到异常。

    否则,您可以尝试(如果适用)通过在方法声明中添加关键字 synchronized 来设置访问列表同步的方法。

    【讨论】:

      【解决方案2】:

      其他人已经指出 add-ing 到 ArrayList 时迭代它是不允许的。

      但无论如何要解决您的问题,看起来您需要在尝试 add 之前遍历整个列表,因为您的循环似乎正在检查是否有任何内容该列表与您的行匹配以避免重复。在这种情况下,您不想在迭代列表时添加到列表中,因为直到最后您才知道列表是否有重复项。

      所以只需遍历并检查是否找到匹配项:

      List<PrivilegeObjectBO> arraylist = new ArrayList<PrivilegeObjectBO>();
      if (rs != null) {
          while (rs.next()) {
      
              boolean found = false;
              for (BO bo : arraylist) {
                   if (bo.getRolepkey() == rs.getInt("ROLE_PKEY")) {      
                       bo.setPrivilegename(rs.getString("SP.NAME"));
                       found = true;
                   }
              }
      
              if (!found) {
                  BO newobj = new BO();
                  newobj.setRolepriviledgepkey(rs.getInt("PRIVILEGE_PKEY"));
                  newobj.setProticolpkey(protocol);                
                  newobj.setPrivilegename(rs.getString("SP.NAME"));
                  newobj.setRolepkey(rs.getInt("SRP.ROLE_PKEY"));
                  arraylist.add(newobj);
              }
          }
      }
      

      除非您确实想为列表中已有的每个不匹配的BO 添加一个新的BO...

      【讨论】:

        【解决方案3】:

        根据ArrayList javadoc

        这个类的迭代器和listIterator返回的迭代器 方法是快速失败的:如果列表在任何结构上被修改 迭代器创建后的时间,除了通过 迭代器自己的删除或添加方法,迭代器会抛出一个 ConcurrentModificationException。

        for (BO bo : arraylist)
        

        上面的for-each循环获取列表的迭代器和

          arraylist.add(newobj);
        

        您试图在不使用迭代器自己的方法的情况下修改列表,导致ConcurrentModificationException

        这里是SO discussion on possible solutions

        【讨论】:

          【解决方案4】:

          在 java 中,当您在迭代集合时修改集合时,您总是会得到 ConcurrentModificationException。

          可能的解决方案:对添加或删除的项目使用临时集合,并在迭代完成后添加或删除这些项目。

          【讨论】:

          • 如果您修改集合,您将始终得到该异常
          【解决方案5】:

          您不能使用 foreach 遍历 ArrayList 并同时向其中添加元素。

          使用迭代器,像这样:

          Iterator<PrivilegeObjectBO> iterator = arraylist.iterator();
          while (iterator.hasNext()) {
            ...
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-06-04
            • 2023-04-09
            • 2016-12-23
            • 1970-01-01
            • 2014-05-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多