简体   繁体   中英

Concurrent modification error when adding elements to LinkedList

I have an List of LinkedList objects.

    List<LinkedList<File1>> backup = new ArrayList<LinkedList<File1>>();

The LinkedList contains some elements. I need to add additional elements dynamically by clicking a button. While doing this, I'm getting a concurrent modification error. I really don't understand why this error is popping up. Here is the code:

private void jButton5ActionPerformed(java.awt.event.ActionEvent evt)      
{                                         
    // When JOIN button is clicked
    int parent_node,dist_node;
    // List<File1> temp_list = new ArrayList<File1>();
    File1 f_new = new File1();
    parent_node = Integer.parseInt(jTextField4.getText());
    dist_node = Integer.parseInt(jTextField5.getText());
    LinkedList<File1> tmp_bk = backup.get(parent_node);
    System.out.println("parent node : " + parent_node);
    System.out.println("dist node : " + dist_node);
    System.out.println("no of lists : " + backup.size());
    f_new.nod = backup.size();
    f_new.dist = dist_node;
    // temp_list.add(f_new);
    tmp_bk.add(f_new);

    ListIterator itr = it_bk.get(parent_node);
    while(itr.hasNext())
    {
        File1 f = (File1)itr.next();
        System.out.println("NODE : " + f.nod + "DIST : " + f.dist);
    }

}     

It's probably because you're editing the list, then trying to use the original iterators. The collections API doesn't allow that . You need to create new iterators after editing the list.

For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

First, if you really expect people to give their attention to your question, you should do them the favor of asking it clearly and in standard English.

Second, you should provide an indication of exactly where in your code you're getting the ConcurrentModificationError.

Finally, what is it_bk ? It just shows up in your code without any explanation. If it is an ArrayList of ListIterators it is certainly possible that its parent_node-th element is in a state where it isn't sure that hasNext() or next() will be safe. I'm guessing you modified the underlying collection with your tmp_bk.add(f_new); and so a pre-existing iterator is worried that its invariants may be violated.

General advice: Don't create and retain iterators (or collections of them). When you want an Iterator, create it, use it, and abandon it.

java.lang.Colletions from JDK 1.5 is not synchronized. In earlier version(jdk 1.4), you wont find this problem.

There are multiple solutions available for these problem and you need to choose one of them wisely as per your use case.

  • Solution 1: The list can be converted to an array with list.toArray() and iterate on the array. This approach is not recommended if the list is large.

  • Answer 2: The entire list can be locked while iterating by wrapping your code within a synchronized block. This approach adversely affects scalability of your application if it is highly concurrent.

  • Answer 3: JDK 1.5 gives you ConcurrentHashMap and CopyOnWriteArrayList classes, which provide much better scalability and the iterator returned by ConcurrentHashMap.iterator() will not throw ConcurrentModificationException while preserving thread-safety.

  • Answer 4: Remove the current object via the Iterator “it” which has a reference to the underlying collection “myStr”. The Iterator object provides it.remove() method for this purpose.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM