Я просто пытаюсь проверить безопасность инициализации полей final, как это гарантирует JLS. Это для статьи, которую я пишу. Однако я не могу заставить его «провалиться» на основе моего текущего кода. Может ли кто-нибудь сказать мне, что я делаю не так, или если это просто что-то, что мне нужно повторять снова и снова, а затем я вижу сбой с каким-то неудачным временем?
Вот мой код:
public class TestClass {
final int x;
int y;
static TestClass f;
public TestClass() {
x = 3;
y = 4;
}
static void writer() {
TestClass.f = new TestClass();
}
static void reader() {
if (TestClass.f != null) {
int i = TestClass.f.x; // guaranteed to see 3
int j = TestClass.f.y; // could see 0
System.out.println("i = " + i);
System.out.println("j = " + j);
}
}
}
и мои потоки называют это так:
public class TestClient {
public static void main(String[] args) {
for (int i = 0; i < 10000; i++) {
Thread writer = new Thread(new Runnable() {
@Override
public void run() {
TestClass.writer();
}
});
writer.start();
}
for (int i = 0; i < 10000; i++) {
Thread reader = new Thread(new Runnable() {
@Override
public void run() {
TestClass.reader();
}
});
reader.start();
}
}
}
Я запускал этот сценарий много-много раз. Мои текущие циклы порождают 10000 потоков, но я закончил с этими 1000, 100000 и даже миллионом. По-прежнему никакой неудачи. Я всегда вижу 3 и 4 для обоих значений. Как я могу заставить это не работать?