错误:java.util.ConcurrentModificationException

时间:2012-12-10 18:38:37

标签: java list struts2 concurrentmodification foreach

我有一个用户选择行的网格, 当点击一行时,它的ID就会发送到我的动作类AddBookToSession.java,并且在病房之后它会将一个列表返回到我的jsp页面invoice.jsp

当用户从我的网格中选择一行时,我收到错误java.util.ConcurrentModificationException

我读了这个similar question,但我仍然无法解决我的问题。

我的问题是:为什么我会收到java.util.ConcurrentModificationException错误,如何解决此问题。请帮我解决这个问题。

控制台出错:

   Dec 10, 2012 11:37:30 PM org.apache.catalina.core.ApplicationDispatcher invoke
   SEVERE: Servlet.service() for servlet jsp threw exception
   java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
    at java.util.ArrayList$Itr.next(ArrayList.java:791)
    at org.apache.struts2.components.IteratorComponent.end(IteratorComponent.java:334)
    at org.apache.struts2.views.jsp.IteratorTag.doAfterBody(IteratorTag.java:87)
       -------------------
        ------------------

invoice.jsp

  <s:if  test="#session['BOK'].size() > 0"> 
         <table width="100%" class="userTable" valign="top" border="0"> 
          <s:iterator value="#session.BOK" status="userStatus">
       <tr class="<s:if test="%{#userStatus.odd == true}">odd</s:if> <s:else>even</s:else>">
             <td width="80%"><s:property value="bookTitile" /></td>
                 <td align="right" width="20%">
                 <s:url id="cancelURL" action="RemovebooksFromSession" namespace="/admin/setups/secure/jspHomepage/bookstransaction">
                         <s:param name="bkid" value="%{id}"></s:param>
                  </s:url>
                <sj:a href="%{cancelURL}" targets="myAdvanceDivBoxx">Rem</sj:a></td>
        </tr>
         </s:iterator>
         </table> 
         </div>
     </s:if>

AddBookToSession.java

  public String execute() 
    {  
        String bookid = request.getParameter("bid"); 
        String qnty=dao.getquantityById(Integer.parseInt(bookid));

        if(qnty.equals("0")||qnty.equals("")||qnty.equals("null")){
            return SUCCESS;
        } 
        Bookdetails book = dao.listBookDetailsById(Integer.parseInt(bookid));
        books = (ArrayList) session.get(BillTransactionBooksConstants.BOK);
        if ( books == null ) books = new ArrayList<Bookdetails>();
        boolean already_exists = false;
        for ( Bookdetails b : books ) 
        {
              if ( Integer.toString(b.getId()).equals(bookid))
            {
                already_exists = true; 
                break;
            }
        }
        if (book != null && !already_exists  ) 
        { 
            books.add(book);
            System.out.println("books size"+books.size()); 
            session.put(BillTransactionBooksConstants.BOK,books);
        }
        return SUCCESS;
    } 

3 个答案:

答案 0 :(得分:0)

从根本上说,你正在修改一个对象,而另一个对象依赖于第一个对象的状态保持不变。

在某种集合对象上使用非修改安全迭代器,然后修改集合时,最常见到这种情况。

我的JSP太生疏了,无法浏览你的源代码,但我看到有几个你似乎在使用迭代器的情况,而JSP中的那个似乎最让人怀疑。

(我相信当您使用多线程以非线程安全的方式管理集合对象时,也会发生此错误。)

答案 1 :(得分:0)

在您的代码执行“books.add(book);”时,页面可能会刷新。在这种情况下,当您在其他人正在使用它时同时修改集合时,您将获得异常。

是否可以修改您的代码,以便您在AddBookToSession中修改的“书籍”是内部书籍列表的副本。

books = new ArrayList<Bookdetails>((ArrayList) session.get(BillTransactionBooksConstants.BOK););

答案 2 :(得分:0)

异常堆栈跟踪指向jsp中的s:iterator,即抛出异常的位置。这意味着当该元素通过书籍列表时,另一段代码会从列表中添加或删除。这可能是您的Java代码或其他一些代码(例如RemovebooksFromSession)。

查看您的代码,并尝试确定在构建jsp页面时是否可能运行其他代码。

无法为您发布的代码提供更多帮助。