Java java.util.ConcurrentModificationException 错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2711817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 22:28:20  来源:igfitidea点击:

Java java.util.ConcurrentModificationException error

javacore

提问by vijay

please can anybody help me solve this problem last so many days I could not able to solve this error. I tried using synchronized method and other ways but did not work so please 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)

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
    }

回答by polygenelubricants

You can't modify a list while you're iterating it, unless you do it through the Iterator.

迭代时不能修改列表,除非您通过Iterator.

From the API: ConcurrentModificationException

从API: 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 Collectionwhile another thread is iterating over it.

当不允许此类修改时,检测到对象的并发修改的方法可能会抛出此异常。

例如,通常不允许一个线程Collection在另一个线程对其进行迭代时对其进行修改。

Your code is a mess, so it's hard to figure out what's going on, but I'd check for:

你的代码一团糟,所以很难弄清楚发生了什么,但我会检查:

  • Shared references
  • All removeANDadd
  • 共享参考
  • 所有removeadd

回答by Sean Owen

I think that simply looking up the javadoc for ConcurrentModificationExceptionwould have answered your question. Did you try that?

我认为只需查找 javadocConcurrentModificationException就可以回答您的问题。你试过吗?

Iterator.remove()is causing the exception, presumably on the linke k.remove(). This means you modified the Listit is iterating over while iterating, which is not allowed. So you need to figure out where c.getDataPoints()is changing. I am guessing it is because you eventually find a cluster d, assign to tempCluster, then change its data points (which is eventually the list you are iterating over.

Iterator.remove()正在导致异常,大概是在 linke 上k.remove()。这意味着您在List迭代时修改了它正在迭代的内容,这是不允许的。所以你需要弄清楚哪里c.getDataPoints()发生了变化。我猜这是因为您最终找到了一个 cluster d,分配给tempCluster,然后更改其数据点(这最终是您要迭代的列表。

回答by iftee

if you need to delete few elements from your list. You can maintain another list like elements to be removed. And finally call removeAll(collection). Of course this is not good for huge data.

如果您需要从列表中删除几个元素。您可以维护另一个列表,例如要删除的元素。最后调用 removeAll(collection)。当然,这对于大数据来说是不利的。

回答by Ankur Shanbhag

Keep few things in mind to avoid concurrent access issues :

请记住以下几点以避免并发访问问题:

First of all the method (startAnalysis) is an instance method. So synchronization will be specific to its instance. So you need to make sure that all the threads trying to access this method must use the same instance to avoid concurrent access issues. If every thread is referring to a different instance, then all the threads will be allowed to execute the method and eventually may lead to concurrency issues.

首先方法(startAnalysis)是一个实例方法。因此同步将特定于其实例。因此您需要确保所有尝试访问此方法的线程必须使用相同的实例以避免并发访问问题。如果每个线程都引用不同的实例,那么所有线程都将被允许执行该方法,最终可能会导致并发问题。

Secondly, one should always prefer to use Iterator rather the for:each loop to iterate over collections, to avoid concurrent access/modification issues.

其次,人们应该总是更喜欢使用 Iterator 而不是 for:each 循环来迭代集合,以避免并发访问/修改问题。

Also you can use concurrent collection apiclasses to avoid concurrency issues. These classes are heavily used in such requirements to avoid concurrent modification issues.

您也可以使用并发集合 api类来避免并发问题。这些类在此类需求中被大量使用,以避免并发修改问题。

Hope this helps.

希望这可以帮助。