错误:java.util.ConcurrentModificationException

错误:java.util.ConcurrentModificationException,java,list,struts2,concurrentmodification,foreach,Java,List,Struts2,Concurrentmodification,Foreach,我有一个网格,用户从中选择行, 单击一行时,它的id将发送到我的操作类AddBookToSession.java,之后它将列表返回到我的jsp页面invoice.jsp 当用户从我的网格中选择一行时,我收到错误java.util.ConcurrentModificationException 我读了这篇文章,但仍然无法解决我的问题 我的问题是:为什么会出现java.util.ConcurrentModificationException错误,以及如何解决这个问题。请帮我解决这个问题 控制台中的错

我有一个网格,用户从中选择行, 单击一行时,它的id将发送到我的操作类
AddBookToSession.java
,之后它将列表返回到我的jsp页面
invoice.jsp

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

我读了这篇文章,但仍然无法解决我的问题

我的问题是:为什么会出现
java.util.ConcurrentModificationException
错误,以及如何解决这个问题。请帮我解决这个问题

控制台中的错误:

invoice.jsp


雷姆
AddBookToSession.java

publicstringexecute()
{  
字符串bookid=request.getParameter(“bid”);
字符串qnty=dao.getquantityById(Integer.parseInt(bookid));
if(qnty.equals(“0”)| | qnty.equals(“null”)){
回归成功;
} 
Bookdetails book=dao.listBookDetailsById(Integer.parseInt(bookid));
books=(ArrayList)session.get(BillTransactionBooksConstants.BOK);
如果(books==null)books=newarraylist();
布尔值已存在=false;
对于(书籍详细信息b:书籍)
{
if(Integer.toString(b.getId()).equals(bookid))
{
已经存在=真;
打破
}
}
如果(book!=null&&!已存在)
{ 
图书。添加(图书);
System.out.println(“books size”+books.size());
session.put(BillTransactionBooksConstants.BOK,books);
}
回归成功;
} 

基本上,您正在修改一个对象,而另一个对象则取决于第一个对象的状态保持不变

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

我的JSP太生疏了,无法浏览您的源代码,但我看到有几种情况下您似乎在使用迭代器,JSP中的迭代器看起来最可疑


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

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

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

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

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

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


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

否。因为如果我应用此代码,则功能将停止。我已经测试过了。你能用类似于我的问题的解决方案解释一下吗?@AshutoshSingh-看看你修改ArrayList的地方(这就是抱怨的地方)。在遍历ArrayList时查看是否正在这样做。我猜“RemovebooksFromSession”是有罪的一方。@AshutoshSingh-提示:实际上看看异常回溯!该JSP看起来像是在会话中从列表中删除书籍的JSP。您确定显示了正确的JSP代码吗?另外,您应该发布更多的stacktrace,例如,当前它缺少JSP名称。@BheshGurung这是正确的JSP。我在会话中添加的列表正在这里迭代。我给了一个要从列表中删除的链接removebook。问题和你说的一样。同一个列表同时执行两个功能。i、 e user在列表迭代并显示在同一页面的同时在列表上添加元素。对于我添加的解决方案,若列表未完全显示,则用户无法在其上添加新值。
  <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>
  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;
    } 
books = new ArrayList<Bookdetails>((ArrayList) session.get(BillTransactionBooksConstants.BOK););