Segolas
Segolas

Reputation: 575

Java, remove elements from multiple threads

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

Answers (2)

formixian
formixian

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

Peter Lawrey
Peter Lawrey

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

Related Questions