Java LinkedList iterator being exhausted prematurely
I am using LinkedList
and retrieving an Iterator
object by using list.iterator()
. After that, I am checking it.hasNext()
, real issue is while checking it.hasNext()
, sometimes it returns false
. I need help why this is happening, though I have elements in the list.
Some code:
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.setR开发者_JAVA百科esponse(obj);
notifyAll();
return;
}
}
Log.Error("validate failed obj.getId="+obj.getId()+" **list.size="+list.size()*This shows 1*);
throw new Exception("InvalidData");
}
...well, hasNext() returns false once you reached the end of the list. Please post your code to see what's wrong. Either you don't have the expected elements in your list or you are calling next() more often than you expect.
Edit: Indeed, since it's multithreaded, Nishant said it right, check that your list is thread safe by using:
List list = Collections.synchronizedList(new LinkedList(...));
Edit 2:
Perhaps two threads are accessing the list concurrently. If the error sometimes happen, sometimes not, this may be the case.
If you have such a piece of code running in several threads:
if (it.hasNext())
T elem = it.next()
process(elem)
It may be that: Thread 1 and 2 say "ok, there is a next element", then switch context, then both become running again at some time and both want to retrieve an element though there is only one available.
To solve this, make your method 'synchronized'
synchronized void processItem(Iterator<T> it)
{
if (it.hasNext())
T elem = it.next()
process(elem)
}
See this, it's not thread safe. If you are using multithreaded code please make sure it is synchronized. See here
"Note that this implementation is not synchronized. If multiple threads access a linked list concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list. If no such object exists, the list should be "wrapped" using the Collections.synchronizedList method. This is best done at creation time, to prevent accidental unsynchronized access to the list:"
List list = Collections.synchronizedList(new LinkedList(...));
After so much debug able to find the root cause and is due to time out between sockets, it was being removed from List,
Thanks Sujeet
精彩评论