Пока циклы не заканчиваются, когда условие выполнено
Насколько я понимаю, следующий код должен нормально завершаться как условие stopRunning = true;
встретил
Однако, когда я запускаю эту программу, она печатает только Last line of Main()
, Start Method ended
никогда не печатается, поскольку цикл while никогда не завершается.
public class Test {
private static boolean stopRunning = false;
public static void main(String[] args) throws Exception {
new Thread(new Runnable() {
@Override
public void run() {
start();
}
}).start();
Thread.sleep(100);
stopRunning = true;
System.out.println("Last line of Main()");
}
public static void start() {
while (!stopRunning) {
}
System.out.println("Start Method ended.");
}
}
Пожалуйста, помогите мне понять это поведение.
3 ответа
Изменение флага на volatile
с
private static volatile boolean stopRunning = false;
будет означать, что другие потоки видят изменение немедленно (из основной памяти вместо кэша), и код выполняется так, как вы ожидаете. Как volatile
относится к модели памяти Java, объясняется, например, в этом руководстве.
Как сказал Мик, вы должны использовать ключевое слово volatile для синхронизации вашей переменной, поэтому при изменении новое значение записывается непосредственно обратно в память, и ваш код будет работать как положено.
Имейте в виду (также указано в статье, с которой связан Мик), что volatile не гарантирует, что можно избежать условий гонки, поэтому, если два разных потока будут читать вашу переменную, небезопасно, что они оба читают одно и то же значение (несмотря на то, что все читается из памяти и на смену прямо отписался)
Как указано в предыдущих ответах:
-
Как сказал Майк - в run() вы должны использовать Test.start() или переименовать метод.Начало, которое вы вызываете, является методом запуска потока. - Также, как заявил Мик, установка stopRunning как volatile должна помочь. Причина, по которой он должен работать, заключается в том, что он удалит кэширование переменной в памяти потока и получит / установит непосредственно из памяти.