Обычная версия
Java форум JavaTalks
форум программистов

Поиск   Пользователи   Группы   Регистрация 
 Профиль   Личные сообщения 

 Вход 

ConcurrentModificationException и как с ним боротся?????????
Список форумов
 ->  Коллекции (Java Collection Framework)


На страницу 1, 2  След. 
Начать новую тему 
Предыдущая тема :: Следующая тема  
Автор Сообщение
loz_a : 163
Новичок
Откуда: Моршин

СообщениеИюн 30, 2008 22:48 
Ответить с цитатой
Есть до ужаса простая програмка....

Код:
import java.util.*;

/**
 * @author Andriy Create a class, then make an initialized array of objects of
 *         your class. Fill a List from your array. Create a subset of your List
 *         using subList( ), and then remove this subset from your List using
 *         removeAll( ).
 */

public class Exercise22 {
   private int i;

   Exercise22(int i) {
      this.i = i;
   }

   public String toString() {
      return "Exercise22 " + i;
   }

   public static void printArray(List<Exercise22> list) {
      for (int i = 0; i < list.size(); i++) {
         System.out.println(list.get(i).toString());
      }
   }

   public static void main(String[] args) {
      List<Exercise22> linkedlist = Collections
            .synchronizedList(new LinkedList<Exercise22>());
      for (int i = 0; i < 20; i++) {
         linkedlist.add(new Exercise22(i));
      }
      printArray(linkedlist);

      List<Exercise22> list = Collections.synchronizedList(linkedlist.subList(8, 16));
       System.out.println();
       printArray(list);
      synchronized (linkedlist) {
         linkedlist.removeAll(list);
      }
      printArray(linkedlist);
   }
}


И ессть до ужаса назоиливое есключение, которое выскакивает в самый не подходящий момент...

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.SubList.checkForComodification(AbstractList.java:855)
at java.util.SubList.listIterator(AbstractList.java:785)
at java.util.AbstractList.listIterator(AbstractList.java:349)
at java.util.SubList.iterator(AbstractList.java:781)
at java.util.AbstractCollection.contains(AbstractCollection.java:94)
at java.util.Collections$SynchronizedCollection.contains(Collections.java:1567)
at java.util.Collections$SynchronizedCollection.contains(Collections.java:1567)
at java.util.AbstractCollection.removeAll(AbstractCollection.java:353)
at java.util.Collections$SynchronizedCollection.removeAll(Collections.java:1594)
at chapter11.Exercise22.main(Exercise22.java:42)


подскажите, пожалуста, как можно побороть его и почему оно у меня выскакивает???? Спасибо....
_________________
Итерация от человека, рекурсия от Бога...
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
Староверъ : 7629
Ктапубеп
Откуда: Elfland

СообщениеИюн 30, 2008 23:25 
Ответить с цитатой
Один из случаев, когда выбрасывается это исключение, это при итерации коллекции и одновременном изменении ее элементов. Я так понимаю, что Collections.synchronizedList() создает новые потоки для работы с коллекцией. Вот и получается, что итерация происходит в одном потоке, а удаляются элементы в другом. Если убрать эту синхронизацию, то все "пучком".
Правда это только предположение.
_________________
JTalks Open Source Project, JT Webinars, JT Interview
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
nazica : 1519
Администратор
Откуда: Donetsk, UA

СообщениеИюл 01, 2008 0:02 
Ответить с цитатой
не, убрать синхронизацию не поможет делу. Перепишите строку кода
Код:
List<Exercise22> list = Collections.synchronizedList(linkedlist.subList(8, 16));

так:
Код:
List<Exercise22> list = Collections.synchronizedList(new LinkedList(linkedlist.subList(8, 16)));

если вызывать просто subList(), то метод всего лишь оборачивает базовую коллекцию так:
Код:
public List<E> subList(int fromIndex, int toIndex) {
        return new SubList<E>(this, fromIndex, toIndex);
    }

Код:
class SubList<E> extends AbstractList<E> {
    private AbstractList<E> l;
    private int offset;
    private int size;
    private int expectedModCount;

    SubList(AbstractList<E> list, int fromIndex, int toIndex) {
        // not important
        l = list;
        offset = fromIndex;
        size = toIndex - fromIndex;
        expectedModCount = l.modCount;
    }
...

Думаю, что неприятности как раз связаны с тем, что используется обертка.
_________________
Software and cathedrals are much the same - first we build them, then we pray


Последний раз редактировалось: nazica (Июл 01, 2008 0:08), всего редактировалось 1 раз
К началу Посмотреть профиль Отправить личное сообщение ICQ Number
loz_a : 163
Новичок
Откуда: Моршин

СообщениеИюл 01, 2008 0:04 
Ответить с цитатой
Да это я уже добавил когда облазил все интернеты и начитался всякого умного...

Код:
public static void main(String[] args) {
      List<Exercise22> linkedlist = new LinkedList<Exercise22>());
      for (int i = 0; i < 20; i++) {
         linkedlist.add(new Exercise22(i));
      }
      printArray(linkedlist);

      List<Exercise22> list = linkedlist.subList(8, 16);
       System.out.println();
       printArray(list);
      synchronized (linkedlist) {
         linkedlist.removeAll(list);
      }
      printArray(linkedlist);
   }
}


Результат тот же самий... Выбивае это мистическое исключение... Shocked
_________________
Итерация от человека, рекурсия от Бога...
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
loz_a : 163
Новичок
Откуда: Моршин

СообщениеИюл 01, 2008 0:11 
Ответить с цитатой
спасибо... Пилюля подействовала... Very Happy
_________________
Итерация от человека, рекурсия от Бога...
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
Староверъ : 7629
Ктапубеп
Откуда: Elfland

СообщениеИюл 01, 2008 6:46 
Ответить с цитатой
Не знаю, у меня, если заменить Collections.synchronizedList(linkedlist.subList(8, 16)); на linkedlist.subList(8, 16), то нормально работает. Confused
_________________
JTalks Open Source Project, JT Webinars, JT Interview
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
loz_a : 163
Новичок
Откуда: Моршин

СообщениеИюл 01, 2008 7:52 
Ответить с цитатой
может IDE здесь имеет какое-то значение.. Question у меня Eclipse...
_________________
Итерация от человека, рекурсия от Бога...
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
nazica : 1519
Администратор
Откуда: Donetsk, UA

СообщениеИюл 01, 2008 9:58 
Ответить с цитатой
хм, а у меня не подествовало. Видно, пора на запчасти %)
_________________
Software and cathedrals are much the same - first we build them, then we pray
К началу Посмотреть профиль Отправить личное сообщение ICQ Number
Староверъ : 7629
Ктапубеп
Откуда: Elfland

СообщениеИюл 01, 2008 11:04 
Ответить с цитатой
Не, у меня тоже Еклипс, да и не имеет это значение. А вот ждк у меня 6-я.
_________________
JTalks Open Source Project, JT Webinars, JT Interview
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
Майоров Павел : 1460
Java Developer

СообщениеИюл 06, 2008 10:22 
Ответить с цитатой
А вот так не пробовали?

linkedlist.subList(8,16).clear(); //удаляет элементы с восьмого по пятнадцатый
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
Shreder : 101
Новичок
Откуда: Kharkov, Ukraine

СообщениеИюл 07, 2008 13:10 
Ответить с цитатой
loz_a писал(а):
Есть до ужаса простая програмка....

Код:
import java.util.*;
      List<Exercise22> linkedlist = Collections
            .synchronizedList(new LinkedList<Exercise22>());



Попробуйте использовать

List<Exercise22> linkedlist = new Vector<Exercise22>();

У меня была подобная проблема и при переходе на вектор, проблема профиксилась сама собой.
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Майоров Павел : 1460
Java Developer

СообщениеИюл 07, 2008 13:50 
Ответить с цитатой
Shreder, ну и какого черта вы советуете перейти на вектор, если это вам не помогло?!

PS для генерации подобного исключения достаточно таких строк кода:

Код:

List<Object> list = new LinkedList<Object>();
//теперь заполним список
...
//теперь совершим нечто страшное!
Iterator<Object> iter = list.getIterator();
list.add(null);
iter.next(); //ошибка!


То есть ошибка возникает при изменении списка в процессе его перебора.
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
Ybr : 7
Новичок

СообщениеАвг 14, 2011 17:53 
Ответить с цитатой
Доброго времени суток, господа.
Пишу простенькую программу. В одном из методов столкнулся с точно таким же исключением. Что пробовал:

Староверъ писал(а):
Один из случаев, когда выбрасывается это исключение, это при итерации коллекции и одновременном изменении ее элементов.

Проанализировал код. Итерация коллекции используется, но, вроде, никаких изменений этой коллекции я не делаю.
nazica писал(а):
Думаю, что неприятности как раз связаны с тем, что используется обертка.

Попробовал вместо Character использовать char - тоже никак не повлияло.

Код метода (вылетает на строке № 27):
Код:
public String BreveCorrector (int i, String s) {
       
        String desBreve;// строка, в которой произошла замена найденной комбинации на бреве
        ArrayList<Character> ordinary = new ArrayList<Character>();// массив для букв без бреве
        ArrayList<Character> abbreve = new ArrayList<Character>();// массив для букв с бреве
        Iterator<Character> o = ordinary.iterator();
        int j = -1;
        char c;
       
        // заполнение таблицы соответствия
        ordinary.add('a'); ordinary.add('A');
        ordinary.add('e'); ordinary.add('E');
        ordinary.add('i'); ordinary.add('I');
        ordinary.add('o'); ordinary.add('O');
        ordinary.add('u'); ordinary.add('U');
       
        abbreve.add('ă'); abbreve.add('Ă');
        abbreve.add('ĕ'); abbreve.add('Ĕ');
        abbreve.add('ĭ'); abbreve.add('Ĭ');
        abbreve.add('ŏ'); abbreve.add('Ŏ');
        abbreve.add('ŭ'); abbreve.add('Ŭ');
       
        // процесс замены найденной комбинации на гласную с бреве
        desBreve = s.substring(0, i);// копируется строка s от начала до того места, где
                                       // надо произвести замену
        while (o.hasNext()) {// замена обычной буквы на букву с бреве
            c = o.next(); j++;
           
            if (!(c != s.charAt(i+1))) desBreve = desBreve + abbreve.get(j).toString();
        }
        desBreve = desBreve + s.substring(i, s.length()-1);// копирование оставшейся части строки s
       
        return desBreve;
    }


Выдаваемая ошибка:
Цитата:
Exception in thread "main" java.util.ConcurrentModificationException <и указание, на каких строках искать>


Интересно будет выслушать ваши мнения.
К началу Посмотреть профиль Отправить личное сообщение
Майоров Павел : 1460
Java Developer

СообщениеАвг 14, 2011 18:17 
Ответить с цитатой
Ваша проблема в том, что вот эта строчка
Код:
Iterator<Character> o = ordinary.iterator();
стоит перед
Код:
ordinary.add('a'); ordinary.add('A');
ordinary.add('e'); ordinary.add('E');
ordinary.add('i'); ordinary.add('I');
ordinary.add('o'); ordinary.add('O');
ordinary.add('u'); ordinary.add('U');
и в итоге получается, что в процессе итерации (который начался в строке 6) меняется содержимое.
Поставьте создание итератора сразу перед циклом while и исключение исчезнет

PS возможно, вместо ArrayList<Character> в этом куске кода следовало бы использовать строки:
Код:
String ordinary = "aAeEiIoOuU";
String abbreve = "ăĂĕĔĭĬŏŎŭŬ";
Строчек кода будет меньше, да и смотреть, какая буква какой соответствует, много проще.

PPS давно уже за форумом не слежу, а уведомления все приходят и приходят Smile
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
Ybr : 7
Новичок

СообщениеАвг 14, 2011 20:20 
Ответить с цитатой
Майоров Павел писал(а):
Поставьте создание итератора сразу перед циклом while и исключение исчезнет

Спасибо, это сработало. Буду знать, что итерирование начинается в месте определения переменной итерации.
Майоров Павел писал(а):
PS возможно, вместо ArrayList<Character> в этом куске кода следовало бы использовать строки<...>

Это моя вечная проблема. Если ухо можно чесать рукой, то я непременно попробую это сделать и левой ногой =)
Поправил.
Майоров Павел писал(а):
PPS давно уже за форумом не слежу, а уведомления все приходят и приходят Smile

Это на руку новичкам вроде меня Wink Спасибо за помощь!
К началу Посмотреть профиль Отправить личное сообщение
 
Начать новую тему  Ответить на тему
Страница 1 из 2
На страницу 1, 2  След.
Список форумов
 -> Коллекции (Java Collection Framework)


 
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Java and all Java-related trademarks and logos are trademarks or registered trademarks of Oracle Corporation in the United States and other countries.
Это сайт не относится к фирме Oracle Corporation и не поддерживается ею.

© 2006-2010 www.javatalks.ru: форум java программистов
Используется скрипт phpBB © 2001, 2010 phpBB Group

Хостинг от bizname.ru