For one thing, according to the Javadoc below:
If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.)
synchronization is not necessary.
For another, setting the value of an element is an atomic action so it cannot be interleaved. However, memory consistency errors are still possible.
So which is right?
Edit: Maybe I haven't expressed myself clearly. Actually, I just wanna know whether the Javadoc is wrong or at least misleading. By the way, I said setting the value of an element is an atomic action, but this is obviously wrong.
I guess what you want is a guarantee that iterators won't be invalidated if List.set(int, E) is called during the iterator's lifetime. I think this is something that varies from one List implementation to another so if the documentation doesn't explicitly say that List.set(int, E) is thread-safe, assume that it isn't. In practice you might find that an array implementation will not invalidate the iterator but you don't want to rely on any undocumented behaviour in a third-party library - if you want to enforce some condition you should do it in your own code.
An example of a class that does provide a guarantee that List.set(int, E) doesn't invalidate iterators, however: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
I don't think it's a good idea to make assumptions on how setting a value in ArrayList is implemented. The important thing is that if you are given no consistency guarantees in the Javadoc, you should always synchronize externally when multiple threads are using the same ArrayList.
Or, depending on the use case, choose a different structure altogether, one that was designed for concurrency, like CopyOnWriteArrayList. (Though always make sure you choose the right one, as they don't perform equally well under all circumstances.)
In this case the Javadoc doesn't explicitly say you can omit sychronization if you only use set(), merely hints at it. And the hint is wrong because as you say, memory consistency isn't guaranteed at all, you can easily end up reading stale values, or multiple set() calls can be reordered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With