当数组变量是易失性的时,我们是否需要同步对数组的访问?

2022-09-02 19:50:03

我有一个类,其中包含对数组的易失性引用:

private volatile Object[] objects = new Object[100];

现在,我可以保证,只有一个线程(调用它)可以写入数组。例如writer

objects[10] = new Object();

所有其他线程将仅读取该线程写入的值。writer

问题:我是否需要同步此类读取和写入以确保内存一致性?

我想,是的,我应该。因为从性能的角度来看,如果 JVM 在写入数组时提供某种内存一致性保证,那么它就没有用了。但我不确定这一点。在文档中没有找到任何有用的东西。


答案 1

您可以使用 AtomicReferenceArray

final AtomicReferenceArray<Object> objects = new AtomicReferenceArray<>(100);

// writer
objects.set(10, new Object());

// reader
Object obj = objects.get(10);

这将确保原子更新和读/写操作之前的一致性,就像数组的每个项都是 一样。volatile


答案 2
private volatile Object[] objects = new Object[100];

你只提到这样。而不是关联的数组实例内容。objectsvolatile

问:我是否需要同步此类读取和写入以确保内存一致性?

是的。

如果JVM在写入数组时提供某种内存一致性保证,那么从性能角度来看,这将是没有用的。

考虑使用类似集合(或您自己的数组包装器,在赋值函数和读取方法中具有一些实现)。CopyOnWriteArrayListLock

Java平台也有(过时的有缺陷的设计)和(对于许多场景来说很慢),但我不建议使用它们。Vectorsynchronized List

PS:@SashaSalauyou的另一个好主意