1

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

4
  • you should syncronize the resource, this way only one thread can access ur collection at one time, thus removes the chances of collision Commented Jun 26, 2014 at 16:44
  • it makes a difference if each thread accessing timersVector could potentially match with the same vector elements as other threads. Commented Jun 26, 2014 at 16:44
  • but yeah, you should look into the "synchronized" keyword in Java Commented Jun 26, 2014 at 16:45
  • @AlexMills no, the tag result of the getTag() method is a UUID so one thread can delete only one element and isn't Vector already synchronized? Commented Jun 26, 2014 at 16:50

2 Answers 2

5

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<>())

Sign up to request clarification or add additional context in comments.

2 Comments

I think this is what I'm looking for. My fear was that if one thread find a match at i=10 but before it can delete the element another thread remove its own match at i=5 then the first thread will be in trouble because i=10 no longer exist. Any advantages of using the Collections.synchronizedList instead of wrapping my foor loop in a synchronized(this) block ??
@Segolas in the code you mention, none at all, in fact it's redundant. Using Collections.synchronizedList is useful if you access the list elsewhere (I assume you add elements somewhere) as it is more defensive. If you know what you are doing you can synchronized(list) everywhere you use the list. I suggest locking the list rather than the whole object as a pattern as this allows for multiple locks which can accessed concurrently.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.