Синхронизация как альтернатива изменчивому объявлению

#java #volatile

#java #volatile

Вопрос:

В этом руководстве (ссылка) по объявлению volatile в Java говорится, что объявление volatile может быть альтернативой синхронизации.

Авторский пример использования объявления volatile:

 volatile boolean shutdownRequested;

...

public void shutdown() { shutdownRequested = true; }

public void doWork() { 
    while (!shutdownRequested) { 
        // do stuff
    }
}
  

Моя наивная реализация синхронизации была бы:

 volatile boolean shutdownRequested;

...

synchronized public void shutdown() { shutdownRequested = true; }

synchronized public void doWork() { 
    while (!shutdownRequested) { 
        // do stuff
    }
}
  

Кажется, что если поток A вызывает, shutdown в то время как поток B уже вызван и выполняется doWork , может показаться, что поток B будет постоянно блокировать выполнение, потому что это цикл. Похоже, это не дает потоку A возможности получить доступ к логическому значению. Что имел в виду автор в качестве синхронизированной альтернативы изменчивому объявлению?

Комментарии:

1. Статья начинается с того, что это volatile в общем случае не заменяет надлежащую формальную блокировку.

2. Да, но этот вопрос о том, как блокировка является альтернативой использованию изменчивого объявления.

Ответ №1:

// do stuff Часть будет находиться за пределами синхронизированного блока. Например, вместо того, чтобы doWork быть синхронизированным и иметь while (!shutdownRequested) , у вас может быть while (!getShutDown()) where getShutDown — синхронизированный метод, который возвращает shutdownRequested .

Ответ №2:

Вот один из способов, которым это могло бы сработать:

 public void doWork() { 
    while (true) {
        synchronized (this) {
            if (shutdownRequested) {
                break;
            }
        }
        // do stuff
    }
}