2010-12-29 4 views
0

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

Некоторый код:

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"); 
} 
+2

Если it.hasNext() == ложь, это означает, что ваш список пуст. Для более полного ответа нам нужно увидеть некоторый код ... – Guillaume

+2

@Sujeet попробуйте отладить путем печати list.size() - маловероятно, что итератор вернет false, даже если в списке есть элементы (если он правильно закодирован) – Nishant

+0

Это многопоточное приложение. Не могу предоставить полный код :(Мне нужна помощь, например, если у вас возник такой вопрос. Есть ли какой-либо сценарий, когда it.hasNext() возвращает false, хотя список не пуст. – Sujeet

ответ

4

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

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

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

Edit 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) 
    } 
+0

end of list? Пожалуйста, объясните подробно об этом ... – Sujeet

+1

@Sujeet: Если ваш список содержит 7 элементов, вы можете вызвать 'it.next()' 7 раз перед 'it.hasNext()' возвращает 'false'. В этот момент вы достигли конца списка. –

+0

Поскольку я ограничиваю свой кеш только 1 элементом. – Sujeet

3

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

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

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

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

Благодаря Sujeet

Смежные вопросы