Java LinkedList итератор преждевременно исчерпан - PullRequest
0 голосов
/ 29 декабря 2010

Я использую LinkedList и извлекаю объект Iterator с помощью list.iterator().После этого я проверяю it.hasNext(), реальная проблема заключается в проверке it.hasNext(), иногда она возвращает false.Мне нужна помощь, почему это происходит, хотя у меня есть элементы в списке.

Какой-то код:

public synchronized void check(Object obj) throws Exception {
    Iterator itr = list.iterator();

    while(itr.hasNext()) { //This Line I get false.. though i have list size is 1

        Item p = (Item)itr.next();
        if(p.getId() == null) {continue;}
        if(p.getId().getElemntId() == obj.getId() || obj.getId() == 0 ) {
            p.setResponse(obj);
            notifyAll();
            return;
        }
    }
    Log.Error("validate failed obj.getId="+obj.getId()+" **list.size="+list.size()*This shows 1*);
    throw new Exception("InvalidData");
}

Ответы [ 3 ]

4 голосов
/ 29 декабря 2010

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

Редактировать: Действительно, поскольку он многопоточный, Нишант сказал правильно, проверьте, что ваш список является потокбезопасно с помощью:

List list = Collections.synchronizedList(new LinkedList(...));

Редактировать 2:

Возможно, два потока одновременно получают доступ к списку.Если ошибка иногда возникает, иногда нет, это может иметь место.

Если у вас есть такой кусок кода, работающий в нескольких потоках:

if (it.hasNext())
  T elem = it.next()
  process(elem)

Это может быть так: Поток 1и 2 говорят: «Хорошо, есть следующий элемент», затем переключаем контекст, затем оба снова запускаются через некоторое время, и оба хотят получить элемент, хотя доступен только один.

Чтобы решить эту проблему, выполнитеваш метод синхронизирован

  synchronized void processItem(Iterator<T> it)
  {
    if (it.hasNext())
      T elem = it.next()
      process(elem)
  }
3 голосов
/ 29 декабря 2010

Смотри, это не потокобезопасно.Если вы используете многопоточный код, пожалуйста, убедитесь, что он синхронизирован. См. Здесь

"Обратите внимание, что эта реализация не синхронизирована. Если несколько потоков обращаются к связанному списку одновременно, и хотя бы один из потоков изменяет список структурно, он должен быть синхронизирован извне.(Структурная модификация - это любая операция, которая добавляет или удаляет один или несколько элементов; простая установка значения элемента не является структурной модификацией.) Обычно это выполняется путем синхронизации с некоторым объектом, который естественным образом инкапсулирует список. Если такого объекта не существует, список должен быть "упакован" с использованием метода Collections.synchronizedList. Это лучше всего делать во время создания, чтобы предотвратить случайный несинхронизированный доступ к списку: "

List list = Collections.synchronizedList(new LinkedList(...));
0 голосов
/ 04 января 2011

После такой большой отладки удалось найти основную причину и из-за истечения времени ожидания между сокетами, она была удалена из списка

Спасибо Sujeet

...