#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
}
}