Reputation: 575
I have multiple threads iterating over a list. All these threads will in the end find a matching element to remove from such list.
To avoid inconsistent states what should I use for the list? Vector? ArrayList? Other?
Here is an example with Vectors. It doesn't give errors but I'm sure it could:
for(int i=0; i<timersVector.size(); i++){
currTimerThread = timersVector.get(i);
if(currTimerThread.getRowViewTag().equals(parent.getTag())){
currTimerThread.stopTimer();
timersVector.remove(i);
Log.i(tag, "timerVector size: "+timersVector.size());
}
}
For example, if one thread is entering the loop and size is 10 and right after another thread is removing the element at 5, what would happen to the first one?
Thanks for any help
Upvotes: 1
Views: 2997
Reputation: 1559
Accessing a List from multiple threads requires a synchronized List wrapper. The java.util.Collections utility class contains all kind of synchronized wrappers.
In your case, wrap your list (don't use Vector, it's there of backward compatibility only) using this simple line of code:
List<Timer> timers = Collections.synchronizedList(originalTimers);
Suggestion: Usage of synchornized map would be more efficient in your case and wouldn't require a loop to search through items.
Upvotes: 1
Reputation: 533530
For a Vector each operation is thread safe, however multiple operations are not. As you are performing multiple operations, you need to hold a lock on the collection while performing them all. i.e. outside the loop in this case.
e.g. the element you get(i) and the element you remove(i) could be changed by another thread. There is no guarantee the element you removed is the one you checked.
BTW ArrayList replaced Vector in 1998. I suggest you use that and synchronize as required and/or use Collections.synchronizedList(new ArrayList<>())
Upvotes: 5