user1964161
user1964161

Reputation: 585

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!

Upvotes: 4

Views: 504

Answers (2)

Peter Lawrey
Peter Lawrey

Reputation: 533740

After object construction, final fields are guaranteed to be visible and correct. As @AlexShavlovsky notes, this extends to the objects referenced by final fields.

There is a simple solution which is to use an ExecutorService. It not only wraps a queue and a thread pool but makes enough access to volatile fields to ensure your data will be correct.

In short, keep it simple, use the standard libraries and it's more likely to work.

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 692073

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).

Upvotes: 4

Related Questions