2014-12-15 3 views
-4

Я хотел избежать синхронизации, поэтому я попытался использовать итераторы. Единственное место, где я могу изменить массив выглядит следующим образом:Почему итераторы не являются решением проблемы CuncurentModificationException?

if (lastSegment.trackpoints.size() > maxPoints) 
    { 
     ListIterator<TrackPoint> points = lastSegment.trackpoints.listIterator(); 
     points.next(); 
     points.remove(); 
    } 
    ListIterator<TrackPoint> points = lastSegment.trackpoints.listIterator(lastSegment.trackpoints.size()); 
    points.add(lastTrackPoint); 

И массив обход выглядит следующим образом:

for (Iterator<Track.TrackSegment> segments = track.getSegments().iterator(); segments.hasNext();) 
    { 
     Track.TrackSegment segment = segments.next(); 
     for (Iterator<Track.TrackPoint> points = segment.getPoints().iterator(); points.hasNext();) 
     { 
      Track.TrackPoint tp = points.next(); 
      //     ^^^ HERE I GET ConcurentModificationException 
      //     ============================================= 
      ... 
     } 
    } 

Итак, что случилось с итераторами? Массивы второго уровня огромны, поэтому я не хочу их копировать, и я не хочу полагаться на синхронизацию за пределами моего класса Track.

+2

я не понимаю ... staahp. Что ты вообще делаешь? Что вы синхронизируете, как выглядит ваш Track-класс .. и почему вы даже думаете, что итераторы волнуют проблемы многопоточности? – Vogel612

+0

Значит, они этого не делают? Тогда я вводил в заблуждение. –

+0

Обратите внимание, что 'ConcurrentModificationException' does * не обязательно имеет что-либо * для работы с многопотоком/параллелизмом. Вы можете легко вызвать это исключение в однопоточном коде. Изменяет ли ваш цикл 'for'' segment.getPoints() '(прямо или косвенно, с помощью какого-либо другого метода)? – yshavit

ответ

1

От https://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

К примеру, это вообще не допустимо для одного потока для изменения коллекции, а другой поток итерации над ним. В общем случае результаты итерации в этих условиях не определены. Некоторые реализации Iterator (, включая те из всех реализаций сбора общего назначения, предоставляемые JRE), могут выбрасывать это исключение, если обнаружено это поведение.

Чтобы избежать исключения, вам необходимо выполнить какую-то синхронизацию. Вы можете использовать Collections.synchronizedList и работать только в этом списке.