另一个ConcurrentModificationException

时间:2012-01-11 01:06:14

标签: java

我是Java的新手,特别是迭代列表并修改它的元素。我经历了几十个类似的问题,但经过多次尝试都没有用。 在以下代码示例中,抛出异常。它与并发线程无关,因为我只有一个线程。 Netbeans输出sais表示异常发生在第5行(CustomerData customer = i.next();):

CustomerData tempCustomer = new CustomerData("",tagID,0);
tempCustomer.setName(name);
tempCustomer.setSize(size);
for(ListIterator<CustomerData> i = customers.listIterator(); i.hasNext(); )
{
    CustomerData customer = i.next();
    if(customer.getTagID().contains(tagID))
    {
        Object[] options = {"overwrite", "do not overwrite"};
        int n = JOptionPane.showOptionDialog(rootPane, 
                                            "TagID already exists. overwrite?", 
                                            "?", 
                                            JOptionPane.YES_NO_OPTION, 
                                            JOptionPane.QUESTION_MESSAGE, 
                                            null, 
                                            options, 
                                            rootPane);
       if ( n == JOptionPane.YES_OPTION ){
           i.set(tempCustomer); 
       }
    }
    else{
        addCustomer();
    }
}

整个代码只应检查元素是否具有匹配的tagID,如果匹配,则替换其中的两个值(名称和大小)。最初我尝试在元素的for循环中使用setName()setSize(),但是在它不起作用并且在阅读其他相关问题之后,我在循环之前将值分配给临时对象使用迭代器的set方法替换当前元素。但仍然没有成功,它甚至似乎永远不会那么远,因为例外是在第5行之后......

3 个答案:

答案 0 :(得分:2)

问题可能是这一行:

        addCustomer();
当你正在迭代它时,

正试图修改customers。这是不允许的。

无论如何,这似乎是一个逻辑错误:大概你只想在循环之后调用addCustomer一次,如果没有客户有正确的tagID,您当前的代码会尝试使用错误的addCustomer每个客户调用tagID。因此,您需要在循环期间使用boolean变量来跟踪是否有任何客户匹配,然后在循环之后,如果合适,请调用addCustomer

答案 1 :(得分:0)

ConcurentModificationException并不总是表明某个对象已被另一个线程同时修改。

在您的情况下,问题可能在于以下(通过addCustomer方法猜测):您正在获取集合的迭代器,然后修改此集合。因为集合被修改,迭代器变得无效并抛出异常。

我的建议是创建temproray客户列表,当您的迭代完成后,您将附加到原始客户列表。

答案 2 :(得分:0)

javadocs中所述:

  

如果一个线程在迭代时直接修改了一个集合   使用失败快速迭代器的集合,迭代器将抛出它   异常。

我想这是在调用addCustomer()后修改customers对象时发生的。您可以将新添加的对象保存在不同的集合中,直到循环结束或退出循环并在添加后重新启动。