Search code examples
javamemoryconcurrencyvisibility

Java Memory Visibility and AtomicReference's


Note:: This question has to do with memory visibility and not "public", "private" etc.

Lets say I had the following class:

public class Data {
    public final byte[] array;
    public final int offset, length;
    public Data(byte[] array, int offset, int length) {...}
    ...
}

(The elements in the above array can change through methods not shown.)

Now suppose I had a queue with the given data in another class:

final ConcurrentLinkedQueue<Data> queue = new ConcurrentLinkedQueue<>();

Now suppose i have the following code in the class with the queue:

Data data = queue.poll();
... code for reading the elements in the data object.

My question is: Are the elements in the array that were set BEFORE the polling of the queue guaranteed to be visible to the thread that polled the data from the queue?

I understand that the elements set after the polling of the queue will not be visible to the reader, I am only interested in the elements set before the polling of the queue.

If not, it is my understanding that the following code put after calling the poll method will ensure the visibility of the array

data = new Data(data.array, data.offset, data.length);

because object construction ensures the full visibility of the object's fields. Is this correct?

Thanks!


Solution

  • The documentation says:

    The methods of all classes in java.util.concurrent and its subpackages extend these guarantees to higher-level synchronization. In particular:

    Actions in a thread prior to placing an object into any concurrent collection happen-before actions subsequent to the access or removal of that element from the collection in another thread.

    so yes, you're guaranteed to see the values in the array that have been set prior to storing the object into the queue. (I'm assuming you don't modify te array once after it has been stored into the queue here).