2015-11-29 5 views
0

Я сейчас читаю Java Concurrency in Practice и есть что-то, что я не могу понять.Значение visibility

public class NoVisibility { 
private static boolean ready; 
private static int number; 
private static class ReaderThread extends Thread { 
public void run() { 
while (!ready) 
Thread.yield(); 
System.out.println(number); 
} 
} 
public static void main(String[] args) { 
new ReaderThread().start(); 
number = 42; 
ready = true; 
} 
} 

и автор говорит

NoVisibility мог зациклится, так как стоимость готового может никогда не стать видна читателю нить.

И нет никаких объяснений или, возможно, это где-то позже, но пока я действительно смущен. Я был бы очень признателен за любые объяснения.

ответ

1

Это означает, что

while (!ready) 
    Thread.yield(); 

будет работать вечно, потому что, Установка готова к истине в основной метод не будет отражать в потоке.

public static void main(String[] args) { 
    new ReaderThread().start(); 
    number = 42; 
    ready = true; 
} 

Вместо этого вы можете использовать термин летучий, который будет обновлять значение, когда есть изменение переменной.

+0

Да, я знаю это, но почему? Почему настройка готовности к истине не отражается в другом потоке? – Stuart

+2

Поскольку значения кэшируются. Очень дорого всегда извлекать значение из основной памяти, поэтому вам нужно явно «поделиться» значением, будь то с помощью энергозависимого поля, синхронизированного блока или другого механизма. – Kayaman

+0

Правильно, вы можете найти больше на этом на http://tutorials.jenkov.com/java-concurrency/volatile.html. – Eranda