Reputation: 4798
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
Reputation: 3654
The code in your question looks thread-safe because:
Bar
uses AtomicLong
which is atomic and thread-safe.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
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