Saša
Saša

Reputation: 4798

is for-each iteration thread safe?

I have one situation in multithreaded environment where there is no logical problem, but I am concerned if the iterator of java Set could break in some corner case. I don't know if this would crash after a while or not:

class Bar{
    AtomicLong a = 0;
    AtomicLong b = 0;

    public void addA(int value){
        a.addAndGet(value);
    }
    public void addB(int value){
        b.addAndGet(value);
    }
}

class Foo{
    Set<Bar> bars = new CopyOnWriteArraySet();

    public void addBarData(Bar bar){
        if (!bars.add(bar)){
            for (Bar b: bars){
                if (bar.equals(b)){
                    b.addA(bar.a);
                    b.addB(bar.b);
                }
            }
        }
    }
}

The problem might be if two threads are calling addBarData(barInstance) at the near time, one is entering inside ifs body, and start to iterate for-each, but the other adds another element into the set at that moment. Would for-loop (or iterator) crash because of the change of elements number or not?

Upvotes: 3

Views: 5447

Answers (2)

m-szalik
m-szalik

Reputation: 3654

The code in your question looks thread-safe because:

  • Class Bar uses AtomicLong which is atomic and thread-safe.
  • The CopyOnWriteArraySet is thread-safe as well (it copies whole array on every write operation).

So it all is thread-safe, you will not get ConcurrentModificationException, and the result of this code is predictable, because the collection you iterate through is in fact immutable.

Upvotes: 2

AlexR
AlexR

Reputation: 115328

No, for-each loop is just a compiler magic that is equivalent to iteration with Iterator for collection and with index for arrays. It does not add any other effects like thread safety.

Upvotes: 3

Related Questions