简体   繁体   English

Java内存可见性和AtomicReference

[英]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 如果没有,我理解在调用poll方法之后放下的代码将确保数组的可见性

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! 谢谢!

The documentation says: 文件说:

The methods of all classes in java.util.concurrent and its subpackages extend these guarantees to higher-level synchronization. java.util.concurrent及其子包中所有类的方法将这些保证扩展到更高级别的同步。 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). (我假设你在将数据存储到队列中之后不会修改te数组)。

After object construction, final fields are guaranteed to be visible and correct. 在对象构造之后,保证最终字段可见且正确。 Note: this doesn't extend to the objects those fields reference. 注意:这不会扩展到这些字段引用的对象。 ie the byte[] might not be consistent (but I suspect it will be on most JVMs) 即byte []可能不一致(但我怀疑它将在大多数JVM上)

There is a simple solution which is to use an ExecutorService. 有一个简单的解决方案是使用ExecutorService。 It not only wraps a queue and a thread pool but makes enough accesses to volatile fields to ensure your data will be correct. 它不仅包装了一个队列和一个线程池,而且对volatile字段进行了足够的访问,以确保您的数据正确无误。

In short, keep it simple, use the standard libraries and it's more likely to work. 简而言之,保持简单,使用标准库,它更有可能工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM