final 以外のフィールドのオブジェクト初期化が不十分な場合にメモリの可視性の問題を再現しようとしています (JLS 17.5 Final Field Semantics、FinalFieldExampleクラスの例)。「ただし、fy は最終的なものではありません。したがって、reader() メソッドは値 4 を表示することが保証されていません」
私はこのコードを試しました:
public class ReorderingTest2 {
public static void main(String[] args) {
for (int i = 0; i < 2500; i++) {
new Thread(new Reader(i)).start();
new Thread(new Writer(i)).start();
}
}
static class Reader implements Runnable {
private String name;
Reader(int i) {
this.name = "reader" + i;
}
@Override
public void run() {
//System.out.println(name + " started");
while (true) {
FinalFieldExample.reader(name);
}
}
}
static class Writer implements Runnable {
private String name;
Writer(int i) {
this.name = "writer" + i;
}
@Override
public void run() {
//System.out.println(name + " started");
while (true) {
FinalFieldExample.writer();
}
}
}
static class FinalFieldExample {
int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader(String name) {
if (f != null) {
int i = f.x;
int j = f.y;
if (i != 3 || j != 4) {
System.out.printf("reader %s sees it!%n", name);
}
}
}
}
}
以前の同様のトピックと同様に、Windows を搭載したさまざまな PC (2 コアから 8 コアまで) と、サーバー側の Solaris 32 コア ボックスでさえ試しましたが、再現できませんでした: fx と fy は常に適切です。 -初期化。
私が答えを得たIntel/x86/x64アーキテクチャの場合、そのようなコンストラクタロジックの並べ替えを防ぐデフォルトのメモリ保証がほとんどあります。Solaris/sparc でも同じことが言えますか?
では、どのアーキテクチャ/OS でこの並べ替えを再現できるでしょうか?