Concurrent modification error when adding elements to LinkedList - java

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.

Related

JAVA java.util.ConcurrentModificationException

I am trying to create simple JAVA program. But since last day, I am having this issue, I cannot fix.
public void receiveUpdate(ArrayList<Connection> connections) {
for(Connection senderConnection : connections) {
for(Connection receiverConnection : this.connections) {
if(senderConnection.getDestination() == receiverConnection.getDestination()) {
if(senderConnection.getDistance() + 1 < receiverConnection.getDistance()) {
senderConnection.setEnabled(false);
senderConnection.setDistance(senderConnection.getDistance() + 1);
this.connections.remove(receiverConnection);
this.connections.add(senderConnection);
}
}
}
senderConnection.setEnabled(false);
senderConnection.setDistance(senderConnection.getDistance() + 1);
this.connections.add(senderConnection);
}
}
In this method I always get error:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at router.Router.receiveUpdate(Router.java:56)
at router.Router.sendUpdate(Router.java:49)
at loader.Loader.notifyNetworkChanges(Loader.java:61)
at loader.Loader.main(Loader.java:102)
I have noticed, that exception doesn't appear if I comment block:
senderConnection.setEnabled(false);
senderConnection.setDistance(senderConnection.getDistance() + 1);
this.connections.add(senderConnection);
Can anyone tell me, where is the problem?
ConcurrentModificationException This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
The problem is here
this.connections.remove(receiverConnection);
This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
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.
Check this out
To solve your problem you need to use Iterator and remove() method like this
Iterator<String> connectionsIterator = connections.iterator();
while (connectionsIterator.hasNext()) {
if (senderConnection.getDistance() + 1 < receiverConnection.getDistance()){
connectionsIterator.remove();
// add the connection to another list other than this.connections.add(senderConnection);
// then when you finish add them back the this.connections
// so you avoid modifying this.connections
}
}
You are actually modifying the collections, while iterating.
this.connections.remove(receiverConnection);
this.connections.add(senderConnection);
Use an Iterator and call remove():
Iterator<String> iter = connections.iterator();
while (iter.hasNext()) {
if (someCondition)
iter.remove();
}
Use Iterator remove method instead of ArrayList
If you are modifying (eg deleting from) the same list you are looping then you are bound to get the ConcurrentModificationException
You can either use an iterator as #ankur-singhal mentioned or make a deep copy of the list and remove from that copy. Then you can assign the reference of the original list to point to the new one that has the modifications.
Another "greedy" approach (but without using iterators) would be to keep all items to be removed in another new list and after ending your for loop then call removeAll(listOfConnectionsToBeRemoved), for example:
before your for loops
ArrayList<Connection> connectionsToBeRemoved = new ArrayList<Connection>();
inside your for loops
connectionsToBeRemoved.add(receiverConnection)
after ending your for loops
this.connections.removeAll(connectionsToBeRemoved)
*you may do the same for connections to be added. Keep them in a new list and then add them all to your connection list.
You are looping through this.connections and inside you are trying to remove from this.connections this will java.util.ConcurrentModificationException. Change your code to use iterator.

ConcurrentModificationException: single thread, two different Hashtables

I'm getting a ConcurrentModificationException CME that seems to differ from the cases asked for in other threads. I'm running a single thread only. Here's my code piece (edited):
for(Type t : other.types.values()) {
types.put(t.getName(), t)
}
The CME occurs in the for statement. types is of type Hashtable<String, Type> and is a non-static member variable in an object of type Obj. other is of type Obj, too, and the code piece is part of a method of Obj. Just before the for loop, I check that this and other, this.types and other.types, as well as this.types.values() and other.types.values() are pairwise different objects. (Also verified by different object ids in the Eclipse debugger).
The CME is reproducable. I have no clue how it can happen in this situation.
#Edit: The code piece comes from a larger tool, which actually supports multi-threading. The number of threads is controllable and this issue occurs when selecting a single thread only. Also in its method, the code is surrounded by two synchronizations: one on types and the other on other.types. So, I guess, it's not a threading problem.
The tool runs on Windows and Linux. We use Java 1.7 with 1.6 compatibility level.
(Sorry for the bad code, it's not mine)
As stated in the javadoc of ConcurrentModificationException:
This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
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.
As you are using a foreach you are actually using an iterator to navigate over the elements of the collection. Typically the implementations of Iterator are throwing the mentioned exception if you are modifying the underlying collection after the creation of the iterator - in your case, the iterator is creator on the first iteration over the collection. The issue is avoidable by using the "classic" for loop:
for(int i=0; i< other.types.values().size(); i++) {
types.put(t.getName(), t)
}
Nevertheless I presume you are trying to add all elements from other.types to types, for that you can simply do:
types.putAll(other.types)
If the two are maps.

How to Redesigning a method in order for it to work

My code results in an java.util.ConcurrentModificationException error. Here is the following code.
Here is the exact error:
java.util.ConcurrentModificationException
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:894)
at java.util.HashMap$KeyIterator.next(HashMap.java:928)
at ca.on.oicr.pinery.lims.gsle.GsleClient.getOrders(GsleClient.java:720)
Line 720 is the second for loop
I posted this question before and was told that "You're adding to orders inside a loop that's looping over the elements of orders, that's what causes the exception. Don't modify a collection you're looping over inside the loop. Likewise with samples". I understand that I to re construct this method and received the following suggestions.
ListIterator<Order> it = orders.listIterator();
while ( it.hasNext() ) {
Order ord = it.next();
if ( ) // some condition
it.remove(); // This wil remove the element that we just got using the next() method
if ( ) // some other condition
it.add(new Order()); // THis inserts the element immediately before the next call to next()
}
Now I am stuck at how to do the adding of the samples and the order when using the iteration method since you would iterate differently though a set, I assume I would use a for loop.
This is the part I am getting confused on how to change in order to not get the java.util.ConcurrentModificationException.
f
So far I have gotten up to here.
java.util.ListIterator<Order> it = orders.listIterator();
while (it.hasNext()) {
it.next().getId();
if (sampleOrderMap.containsKey((it.next().getId())))
{
Set<OrderSample> samples = sampleOrderMap.get(it.next().getId());
}
}`
I just do not know how to put in the rest in a way that I would not get the ConcurrentModificationException
From Java Docs:
ConcurrentModificationException may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
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.
Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast operations throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.
To go around this, you can create a temporary collection to add to other than the one you are iterating through.
Then, after you finish iterating, you can use orders.AddAll(tempCollection) to add the new items.

Java Enumeration vs Iterator

Enumeration doesn't throw ConcurrentModificationException , why?
See below code .
public static void main(String[] args) {
Vector<String> v=new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
v.add("Sumit");
v.add("Aron");
v.add("Trek");
Enumeration<String> en=v.elements();
while(en.hasMoreElements())
{
String value=(String) en.nextElement();
System.out.println(value);
v.remove(value);
}
}
It only prints :
Amit
Pathak
Aron
Why is this such behavior . Can we say that Enumerator is thread safe.
Edit: When working with Iterator it throws ConcurrentModificationException in single thread application.
public static void main(String[] args) {
Vector<String> v=new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
v.add("Sumit");
v.add("Aron");
v.add("Trek");
Iterator<String> it=v.iterator();
while(it.hasNext())
{
String value=(String) it.next();
System.out.println(value);
v.remove(value);
}
}
Please check.
Note that ConcurrentModificationException has nothing to do with concurrency in the sense of multithreading or thread safety. Some collections allow concurrent modifications, some don't. Normally you can find the answer in the docs. But concurrent doesn't mean concurrently by different threads. It means you can modify the collection while you iterate.
ConcurrentHashMap is a special case, as it is explicitly defined to be thread-safe AND editable while iterated (which I think is true for all thread-safe collections).
Anyway, as long as you're using a single thread to iterate and modify the collection, ConcurrentHashMap is the wrong solution to your problem. You are using the API wrongly. You should use Iterator.remove() to remove items. Alternatively, you can make a copy of the collection before you iterate and modify the original.
EDIT:
I don't know of any Enumeration that throws a ConcurrentModificationException. However, the behavior in case of a concurrent modification might not be what you expect it to be. As you see in you example, the enumeration skips every second element in the list. This is due to it's internal index being incremented regardless of removes. So this is what happens:
en.nextElement() - returns first element from Vector, increments index to 1
v.remove(value) - removes first element from Vector, shifts all elements left
en.nextElement() - returns second element from Vector, which now is "Pathak"
The fail-fast behavior of Iterator protects you from this kind of things, which is why it is generally preferable to Enumberation. Instead, you should do the following:
Iterator<String> it=v.iterator();
while(it.hasNext())
{
String value=(String) it.next();
System.out.println(value);
it.remove(); // not v.remove(value); !!
}
Alternatively:
for(String value : new Vector<String>(v)) // make a copy
{
String value=(String) it.next();
System.out.println(value);
v.remove(value);
}
The first one is certainly preferable, as you don't really need the copy as long as you use the API as it is intended.
Enumeration doesn't throw ConcurrentModificationException , why?
Because there is no path in the code being invoked which throws this exception. Edit: I am referring to the implementation provided by the Vector class, not about the Enumeration interface in general.
Why is this such behavior . Can we say that Enumerator is thread safe.
It is thread-safe in a sense that the code executed is properly synchronized. However, I don't think the result your loop yields is what you would except.
The reason for your output is that the Enumeration object maintains a counter, which is incremented after every invokation of nextElement(). This counter is not aware of your invokation of remove().
the fail-fast behaviour which throws the ConcurrentModificationException is only implemented for the Iterator as you can read in
http://docs.oracle.com/javase/6/docs/api/java/util/Vector.html
Concurrent modification here has nothing to do with threads.
Concurrency here simply means that you are modifying the collection while you are iterating over it. (In your example this happens in the same thread.)
Iterators and enumerations of collections can throw ConcurrentModificationException in this case, but don't have to. The ones that do exhibit fail-fast behaviour. Apparently, the enumeration of Vector isn't fail-fast.
Thread-safety obviously involves multiple threads somehow. Vector is thread-safe only in the sense that its operations (like add, get, etc.) are synchronized. This is to avoid non-deterministic behaviour when one thread is adding an element while at the same time another thread is trying to remove one for example.
Now, when one thread is structurally modifying your collection while another thread is iterating over it, you have to deal with both thread-safety and concurrent modification issues. In this case, and probably in general, it is safest not to rely on ConcurrentModificationException being thrown. It is best to choose the appropriate collection implementation (a thread-safe one for example) and avoid/disallow concurrent modification yourself.
Some iterators allow adding/setting/removing elements through the iterator itself. This can be a good alternative if you really need concurrent modification.
Short answer: It's a bonus feature that was invented after enumeration was already there, so the fact that the enumerator does not throw it does not suggest anything particular.
Long answer:
From wikipedia:
Collection implementations in pre-JDK 1.2 [...] did not contain a
collections framework. The standard methods for grouping Java
objects were via the array, the Vector, and the Hashtable classes,
which unfortunately were not easy to extend, and did not implement a
standard member interface. To address the need for reusable
collection data structures [...] The
collections framework was designed and developed primarily by Joshua
Bloch, and was introduced in JDK 1.2.
When the Bloch team did that, they thought it was a good idea to put in a new mechanism that sends out an alarm (ConcurrentModificationException) when their collections were not synchronized properly in a multi-threaded program. There are two important things to note about this mechanism: 1) it's not guaranteed to catch concurrency bugs -- the exception is only thrown if you are lucky. 2) The exception is also thrown if you misuse the collection using a single thread (as in your example).
So, a collection not throwing an ConcurrentModificationException when accessed by multiple threads does not imply it's thread-safe either.
It depends on how you get the Enumeration. See the following example, it does throw ConcurrentModificationException:
import java.util.*;
public class ConcurrencyTest {
public static void main(String[] args) {
Vector<String> v=new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
v.add("Sumit");
v.add("Aron");
v.add("Trek");
Enumeration<String> en=Collections.enumeration(v);//v.elements();
while(en.hasMoreElements())
{
String value=(String) en.nextElement();
System.out.println(value);
v.remove(value);
}
System.out.println("************************************");
Iterator<String> iter = v.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
iter.remove();
System.out.println(v.size());
}
}
}
Enumeration is just an interface, it's actual behavior is implementation-dependent. The Enumeration from the Collections.enumeration() call wraps the iterator in someway, so it's indeed fail-fast, but the Enumeration obtained from calling the Vector.elements() is not.
The not-fail-fast Enumeration could introduce arbitrary, non-deterministic behavior at an undetermined time in the future. For example: if you write the main method as this, it will throw java.util.NoSuchElementException after the first iteration.
public static void main(String[] args) {
Vector<String> v=new Vector<String>();
v.add("Amit");
v.add("Raj");
v.add("Pathak");
Enumeration<String> en = v.elements(); //Collections.enumeration(v);
while(en.hasMoreElements())
{
v.remove(0);
String value=(String) en.nextElement();
System.out.println(value);
}
}
remove the v.remove(value) and everything will work as expected
Edit: sorry, misread the question there
This has nothing to do with threadsafety though. You're not even multithreading so there is no reason Java would throw an exception for this.
If you want exceptions when you are changing the vector make it Unmodifiable

I keep getting java.util.concurrentmodificationexception.. How to fix this?

I've been working on this snippet of code. Here is the pseudocode of what I want to happen:
a.check if sections(which is a list) size is 0.
b.if sections size is 0, then automatically enroll the student to the section by calling sections.add(newSection)
c.else if sections size is not zero, check for conflicts with schedule
d.if there are no conflicts, then enroll the student to the section by calling sections.add(newSection)
e.else do nothing
Java keeps throwing "java.util.concurrentmodificationexception" error on me. I know, I'm not supposed to alter the size of the ArrayList while traversing the list because it will modify the iterator. Is there another way to solve this? :D
Thanks a lot.
Your help is highly appreciated. :)
public String enrollsTo(Section newSection){
StringBuffer result = new StringBuffer();
String resultNegative = "Failed to enroll in this section.";
String resultPositive = "Successfully enrolled in section: " + newSection.getSectionName() + ".";
int previousSectionSize = sections.size();
if(this.sections.isEmpty()){
this.sections.add(newSection);
result.append(resultPositive);
}else{
for(Iterator<Section> iterator = sections.iterator(); iterator.hasNext() ; ){
Section thisSection = iterator.next();
if(thisSection.conflictsDayWith(newSection)==false &&
thisSection.conflictsTimeWith(newSection)==false){
this.sections.add(newSection); //<-- i believe the problem lies here.
result.append(resultPositive);
}
}
}
// if(this.sections.size() == previousSectionSize){
// result.append(resultNegative);
// }
return result.toString();
}
Don't do sections.add(newSection) inside your for loop, as this is a modification of the collection you're currently iterating over.
Also, don't you want to check all sections before deciding whether to add the newSection or not? Maybe something like this:
boolean conflict = false;
for (...) {
if (/* check for conflict */) {
conflict = true;
break;
}
}
if (!conflict) {
sections.add(newSection);
}
From the javadoc for ConcurrentModificationException (my emphasis):
This exception may be thrown by methods that have detected concurrent
modification of an object when such modification is not permissible.
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.
Note that fail-fast behavior cannot be guaranteed as it is, generally
speaking, impossible to make any hard guarantees in the presence of
unsynchronized concurrent modification. Fail-fast operations throw
ConcurrentModificationException on a best-effort basis. Therefore, it
would be wrong to write a program that depended on this exception for
its correctness: ConcurrentModificationException should be used only
to detect bugs.
Potential solution: instead of adding directly to the list you're iterating, add to a temporary list and then when you've finished iterating, do an addAll().
While iterating collection, you can't modify it. The line this.sections.add(newSection); throwing the exception. You may need to use some boolean marker to check the condition
if(thisSection.conflictsDayWith(newSection)==false &&
thisSection.conflictsTimeWith(newSection)==false)
After the for loop if your boolean marker is true, then you can write
this.sections.add(newSection);
result.append(resultPositive);
You're correct in your assumption,
this.sections.add(newSection);
is definitely the source of your problem.
Simplest solution: Have a boolean representing the section's availability. Start out assuming it is available. If there is any conflict in your iterator, set it to false. After the iterator, add the section if the section is available (boolean true).
ConcurrentModificationExceptions often occur when you are modifying a collection while you are iterating over its elements. Read this tutorial for more details and this old SO post Why does it.next() throw java.util.ConcurrentModificationException?
I agree with #sudocode that you don't want to be adding the newSection every time you find even a section which doesn't conflict. I would have thought that when you step through the code in your debugger this would be apparent. ;)
BTW another (more obscure) way to do this without a flag is
CHECK: {
for (...) {
if (/* check for conflict */)
break CHECK;
}
sections.add(newSection);
}

Categories

Resources