在我的场景中,我的DirtyArray对象基本上是原始数组包装器,它们在发生写访问时设置一个布尔“脏”标志。
public class DirtyArray {
private byte[] data;
public DirtyArray(byte[] data) {
this.data = data;
}
private boolean dirty = false;
public void setValue(int index, byte value) {
dirty = true;
data[index] = value;
}
public boolean isDirty() {
return dirty;
}
}
Run Code Online (Sandbox Code Playgroud)
脏标志只从false到true。
我需要确保并发使用是安全的:有一个或多个线程可以修改数组 ( setValue)。有一个或多个线程DirtyArray在它被 GC 之前捕获,并且如果它已被修改,应该将它写到磁盘上 ( isDirty)。
现在,如果我理解正确的话,像上面那样做是不安全的:实际上,从isDirty线程的角度来看,data[index]=value可以在dirty=true存储之前对存储进行重新排序。因此,看到isDirty()==false并不能保证data没有被修改。
这样对吗?
假设是,那么制作dirty标志volatile应该可以解决这个问题。但是,在以下基准测试中,我看到执行此操作时速度降低了约 …