Java непустой l oop повлияет на статистику чтения потока c переменные? - PullRequest
2 голосов
/ 06 мая 2020

Узнав ключевое слово volatile, я нашел { ссылка }. Я делаю некоторые изменения, но получаю запутанный результат. Вот мой код:

import java.util.concurrent.*;

public class VolatileTest {

    // public static volatile int finished = 0; // 1
    public static int finished = 0; // 2

    public static void main(String[] args) throws ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(2);

        Future<?> future = executor.submit(()->{
            while (finished == 0) {
                // when comment the below if-block, result confused
                if(Thread.currentThread().isInterrupted()){
                    System.out.println("???");
                    break;
                }
            }
        });

        executor.submit(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignored) {
                ;
            } finally {
                finished = 1;
            }
        });

        System.out.println("Started..");

        try{
            future.get(5, TimeUnit.SECONDS);
            System.out.println("finished");
        } catch (TimeoutException | InterruptedException e){
            System.out.println("timeout!");
        } finally {
            future.cancel(true);
        }

        executor.shutdown();
    }
}

этот код работает нормально и выводит

Started..
finished

, но когда я комментирую блок if в первой отправке, вывод будет

Started..
timeout!

Но процесс все еще выполняется, и кажется, что l oop без возврата.

Итак, мой вопрос: непустой l oop повлияет на состояние чтения потока. c переменные?

1 Ответ

4 голосов
/ 06 мая 2020

Если в while нет ничего oop:

while (finished == 0) {}

, JVM может эффективно выполнять это как:

if (finished == 0) while (true) {}

, потому что у него нет указаний на то, что finished может быть изменен таким образом, что ему нужно читать (потому что finished не является изменчивым, а внутри l oop нет ничего, что могло бы в противном случае создать событие «случилось раньше»).

...