Пожалуйста, смотрите код ниже, он представляет цикл Infinite довольно на x86.
Пробовал с jdk8 и jdk7
package com.snippets;
public class SharedVariable {
private static int sharedVariable = 0;// declare as volatile to make it work
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
sharedVariable = 1;
}
}).start();
for(int i=0;i<1000;i++) {
for(;;) {
if(sharedVariable == 1) {
break;
}
}
}
System.out.println("Value of SharedVariable : " + sharedVariable);
}
}
Хитрость заключается не в том, чтобы процессор делал переупорядочение, а в том, чтобы сделать
компилятор для оптимизации, которая вносит ошибку видимости.
Если вы запустите приведенный выше код, вы увидите, что он зависает бесконечно, потому что он никогда не видит обновленное значение sharedVariable.
Чтобы исправить код, объявите sharedVariable как volatile.
Почему обычная переменная не работает и вышеприведенная программа зависает?
- sharedVariable не был объявлен как volatile.
Теперь, поскольку sharedVariable не была объявлена как volatile, компилятор оптимизирует код.
Он видит, что sharedVariable не будет изменен, так почему я должен читать
из памяти каждый раз в цикле. Это выведет sharedVariable из цикла. Нечто похожее на ниже.
for(int i=0i<1000;i++)/**compiler reorders sharedVariable
as it is not declared as volatile
and takes out the if condition out of the loop
which is valid as compiler figures out that it not gonna
change sharedVariable is not going change **/
if(sharedVariable != 1) {
for(;;) {}
}
}
Общий доступ на github: https://github.com/lazysun/concurrency/blob/master/Concurrency/src/com/snippets/SharedVariable.java