Ваши переменные ограничены одним потоком, поэтому нет другого потока, обращающегося к ним. Таким образом, volatile
не имеет значения.
Если вы объявите их static
, они будут разделены между различными потоками. Однако даже в этом случае вы не сможете наблюдать разницу между вашей изменчивой и энергонезависимой переменной. Цитата Java-параллелизма на практике , гл. 3.1.4:
Эффекты видимости изменчивых переменных выходят за пределы значения самой изменчивой переменной. Когда поток A записывает в переменную volatile и впоследствии поток B считывает эту же переменную, значения всех переменных, которые были видны A до записи в переменную volatile, становятся видимыми для B после считывания переменной volatile. Таким образом, с точки зрения видимости памяти написание энергозависимой переменной похоже на выход из синхронизированного блока, а на чтение энергозависимой переменной похоже на вход в синхронизированный блок.
В вашем случае код сначала изменяет переменную volatile, поэтому обновленное значение другой переменной может быть невидимым для другого потока. Пока все хорошо.
Однако, поскольку вы печатаете значения переменных из того же потока, который их изменил , вы все равно не увидите никакой разницы.
Обновление2: Попробуйте эту модифицированную версию (примечание: я ее не тестировал):
class ExampleThread extends Thread {
private static int testValue1;
private static volatile int testValue;
private int newValue;
public ExampleThread(String str, int newValue){
super(str);
this.newValue = newValue;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(getName() + " testValue1 before update: " + testValue1);
System.out.println(getName() + " testValue before update: " + testValue);
testValue = i * newValue;
testValue1 = i * newValue;
System.out.println(getName() + " testValue1 after update: " + testValue1);
System.out.println(getName() + " testValue after update: " + testValue);
sleep(10);
}
}
}
public class VolatileExample {
public static void main(String args[]) {
new ExampleThread("Thread 1 ", 5).start();
new ExampleThread("Thread 2 ", 10).start();
}
}
Обновление: относительно видимости статических полей - снова из того же тома (глава 16.2.3):
[...] статически инициализированные объекты не требуют явной синхронизации ни во время построения, ни при обращении к ним. Однако это относится только к состоянию as-built - если объект является изменяемым, то и читатели, и писатели все еще требуют синхронизации, чтобы сделать видимыми последующие изменения и избежать повреждения данных.