繁体   English   中英

Java内存可见性和AtomicReference

[英]Java Memory Visibility and AtomicReference's

注意::这个问题与内存可见性有关,而不是“公共”,“私人”等。

可以说我有以下课程:

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

(上述数组中的元素可以通过未显示的方法进行更改。)

现在假设我在另一个类中有一个包含给定数据的队列:

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

现在假设我在队列中有以下代码:

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

我的问题是: 在轮询队列之前设置的数组中的元素是否保证对从队列中轮询数据的线程可见?

我知道在轮询队列之后设置的元素对读者来说是不可见的,我只对轮询队列之前设置的元素感兴趣。

如果没有,我理解在调用poll方法之后放下的代码将确保数组的可见性

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

因为对象构造可确保对象字段的完全可见性。 它是否正确?

谢谢!

文件说:

java.util.concurrent及其子包中所有类的方法将这些保证扩展到更高级别的同步。 特别是:

在将对象放入任何并发集合之前的线程中的操作发生在从另一个线程中的集合访问或移除该元素之后的操作之前。

所以是的,您可以保证在将对象存储到队列之前看到数组中已经设置的值。 (我假设你在将数据存储到队列中之后不会修改te数组)。

在对象构造之后,保证最终字段可见且正确。 注意:这不会扩展到这些字段引用的对象。 即byte []可能不一致(但我怀疑它将在大多数JVM上)

有一个简单的解决方案是使用ExecutorService。 它不仅包装了一个队列和一个线程池,而且对volatile字段进行了足够的访问,以确保您的数据正确无误。

简而言之,保持简单,使用标准库,它更有可能工作。

暂无
暂无

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

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