我为线程分配了一个非常大的字节数组来读取和写入数组中的字节。写操作是将新字节直接分配给数组中的值,如byte[i] = byte2;
我可以确保这些操作不会发生冲突(字节数组中的相同部分不会被2个不同的线程写入。当读取一个部分时,其他线程不执行写操作)。我担心的是对阵列的修改是否可以立即用于其他线程。我知道可能有内存栅栏,其他线程仍然可以读取数组中的旧值。
如果问题存在,该如何避免? volatile byte[] store;
会在这种情况下运作吗?
答案 0 :(得分:4)
对阵列的修改是否可以立即用于其他线程。
不是没有作家的写围栏和阅读器的阅读围栏。
我知道可能有内存栅栏,其他线程仍然可以读取数组中的旧值。
您需要使用其中一个用于读写器(不是每个字节一个,每个操作一个)
将volatile byte []存储;在这种情况下工作?
它不会做你想要的,虽然它会减慢你的应用程序。当你这样做
store[i] = b;
当你正在读取store
对byte []的引用时,这增加了一个读取栅栏。
最佳解决方案是使用Unsafe来完全控制这些读写操作。请参阅AtomicIntegerArray的代码。
但是,如果不走这条路,你可以做一个像这样的虚拟操作,这种操作不是那么高效/优雅,但实现起来要简单得多。
private final AtomicBoolean fence = new AtomicBoolean();
public void readFence() {
fence.get();
}
public void writeFence() {
fence.set(true);
}
要使其正常工作,您必须在所有写入后执行writeFence()
,并在所有写入之前执行readFence()
。
如果您正在使用更低级别的路由,您可能会发现使用off heap memory是一个优势。关闭堆内存可以存储非常大(TB)的数据量,而不会影响GC。
答案 1 :(得分:-2)
您可以使用SynchronizedList
实施例
byte[] c = new byte[];
List list = Collections.synchronizedList(Arrays.asList(c));
它将是线程安全的