Java error java.util.ConcurrentModificationException
please someone can help me solve this problem in the last few days, I could not solve this error. I tried using synchronized method and other ways but didn't work, so help me
Error
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.remove(Unknown Source)
at JCA.startAnalysis(JCA.java:103)
at PrgMain2.doPost(PrgMain2.java:235)
The code
public synchronized void startAnalysis() {
//set Starting centroid positions - Start of Step 1
setInitialCentroids();
Iterator<DataPoint> n = mDataPoints.iterator();
//assign DataPoint to clusters
loop1:
while (true) {
for (Cluster c : clusters)
{
c.addDataPoint(n.next());
if (!n.hasNext())
break loop1;
}
}
//calculate E for all the clusters
calcSWCSS();
//recalculate Cluster centroids - Start of Step 2
for (Cluster c : clusters) {
c.getCentroid().calcCentroid();
}
//recalculate E for all the clusters
calcSWCSS();
// List copy = new ArrayList(originalList);
//synchronized (c) {
for (int i = 0; i < miter; i++) {
//enter the loop for cluster 1
for (Cluster c : clusters) {
for (Iterator<DataPoint> k = c.getDataPoints().iterator(); k.hasNext(); ) {
// synchronized (k) {
DataPoint dp = k.next();
System.out.println("Value of DP" +dp);
//pick the first element of the first cluster
//get the current Euclidean distance
double tempEuDt = dp.getCurrentEuDt();
Cluster tempCluster = null;
boolean matchFoundFlag = false;
//call testEuclidean distance for all clusters
for (Cluster d : clusters) {
//if testEuclidean < currentEuclidean then
if (tempEuDt > dp.testEuclideanDistance(d.getCentroid())) {
tempEuDt = dp.testEuclideanDistance(d.getCentroid());
tempCluster = d;
matchFoundFlag = true;
}
//if statement - Check whether the Last EuDt is > Present EuDt
}
//for variable 'd' - Looping between different Clusters for matching a Data Point.
//add DataPoint to the cluster and calcSWCSS
if (matchFoundFlag) {
tempCluster.addDataPoint(dp);
//k.notify();
// if(k.hasNext())
k.remove();
for (Cluster d : clusters) {
d.getCentroid().calcCentroid();
}
//for variable 'd' - Recalculating centroids for all Clusters
calcSWCSS();
}
//if statement - A Data Point is eligible for transfer between Clusters.
// }// syn
}
//for variable 'k' - Looping through all Data Points of the current Cluster.
}//for variable 'c' - Looping through all the Clusters.
}//for variable 'i' - Number of iterations.
// syn
}
a source to share
You cannot change the list while it is iterating, unless you do it through Iterator
.
From the API: ConcurrentModificationException
This exception can be thrown by methods that have detected a concurrent modification of an object if such a modification is invalid.
For example, one thread is usually not allowed to modify
Collection
and the other thread iterates over it.
Your code is a mess, so it's hard to figure out what's going on, but I would check:
- General links
- All
remove
Andadd
a source to share
I think just searching the javadoc for ConcurrentModificationException
would answer your question. Have you tried this?
Iterator.remove()
raises an exception, presumably on linke k.remove()
. This means that you have changed the value List
that is being iterated over, iterated over, which is not allowed. So you need to figure out where is c.getDataPoints()
changing. I assume this is because you will eventually find the cluster d
, assign tempCluster
and then change its data points (this is ultimately the list you are iterating over.
a source to share
Don't remember to avoid concurrent access issues:
First of all, the (startAnalysis) method is an instance method. Thus, the synchronization will be specific to its instance. Therefore, you need to make sure that all threads trying to access this method must use the same instance to avoid concurrent access problems. If each thread refers to a different instance, then all threads will be allowed to execute that method and may eventually lead to concurrency issues.
Second, you should always use an Iterator rather than: each loop to iterate over collections to avoid concurrent access / modification problems.
Also you can use parallel collections api to avoid concurrency issues. These classes are heavily used in such requirements to avoid concurrent changes.
Hope it helps.
a source to share