I have a class containing a volatile reference to an array:
private volatile Object[] objects = new Object[100];
Now, I can guarantee that, only one thread (call it writer
) can write to the array. For example,
objects[10] = new Object();
All other threads will only read values written by the writer
thread.
Question: Do I need to synchronize such reads and writes in order to ensure memory consistency?
I presume, yes I should. Because it would not be useful from performance standpoint if JVM provides some kind of memory consistency guarantees when writing to an array. But I'm not sure about that. Didn't find anything helpful in documentation.
Effectively, a variable declared volatile must have its data synchronized across all threads, so that whenever you access or update the variable in any thread, all other threads immediately see the same value.
Yes, you can make the array volatile but that will only cover change to the reference variable pointing to an array, it will not cover changes in individual array elements.
We can use Collections. synchronizedList(List<T>) method to synchronize collections in java. The synchronizedList(List<T>) method is used to return a synchronized (thread-safe) list backed by the specified list.
Synchronizing on the array only locks on the array (in Java an array is an object). If you synchronize on some array individual element, suppousing they are objects and not primitives, that is another different lock. You can have one without the other, and the inverse is also true. You can´t synchronize on a primitive.
You may use AtomicReferenceArray
:
final AtomicReferenceArray<Object> objects = new AtomicReferenceArray<>(100);
// writer
objects.set(10, new Object());
// reader
Object obj = objects.get(10);
This will ensure atomic updates and happens-before consistency of read/write operations, the same as if each item of array was volatile
.
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