Java java.util.ConcurrentModificationException error - PullRequest
2 голосов
/ 26 апреля 2010

, пожалуйста, кто-нибудь может мне помочь решить эту проблему так долго, что я не мог решить эту ошибку. Я пытался использовать синхронизированный метод и другие способы, но не сработало, поэтому, пожалуйста, помогите мне

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)

код

 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
    }

Ответы [ 4 ]

8 голосов
/ 26 апреля 2010

Вы не можете изменять список во время его итерации, если вы не сделаете это через Iterator.

Из API: ConcurrentModificationException

Это исключение может быть вызвано методами, которые обнаружили одновременную модификацию объекта, когда такая модификация недопустима.

Например, как правило, один поток не может изменять Collection, пока другой поток итерирует по нему.

Ваш код беспорядок, поэтому трудно понять, что происходит, но я бы проверил:

  • Общие ссылки
  • Все remove И add
3 голосов
/ 26 апреля 2010

Я думаю, что просто поиск javadoc для ConcurrentModificationException ответил бы на ваш вопрос. Вы пробовали это?

Iterator.remove() вызывает исключение, предположительно на линке k.remove(). Это означает, что вы изменили List, который он повторяет во время итерации, что недопустимо. Так что вам нужно выяснить, где c.getDataPoints() меняется. Я предполагаю, что это потому, что вы в конечном итоге находите кластер d, присваиваете tempCluster, а затем изменяете его точки данных (что в конечном итоге является списком, по которому вы перебираете.

0 голосов
/ 15 марта 2013

Помните о нескольких вещах, чтобы избежать проблем одновременного доступа:

Прежде всего метод (startAnalysis) является методом экземпляра.Поэтому синхронизация будет зависеть от его экземпляра.Поэтому вам нужно убедиться, что все потоки, пытающиеся получить доступ к этому методу, должны использовать один и тот же экземпляр, чтобы избежать проблем одновременного доступа.Если каждый поток ссылается на отдельный экземпляр, то всем потокам будет разрешено выполнить метод, что в конечном итоге может привести к проблемам с параллелизмом.

Во-вторых, всегда следует предпочитать использовать Iterator, а не цикл for: eachперебирать коллекции, чтобы избежать одновременных проблем доступа / модификации.

Также вы можете использовать классы api для одновременной коллекции, чтобы избежать проблем с параллелизмом.Эти классы интенсивно используются в таких требованиях, чтобы избежать одновременных проблем модификации.

Надеюсь, это поможет.

0 голосов
/ 12 июня 2010

, если вам нужно удалить несколько элементов из вашего списка. Вы можете сохранить другой список, например, элементы, которые будут удалены. И, наконец, вызовите removeAll (collection). Конечно, это плохо для больших данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...