同步作为 volatile 声明的替代方案

Synchronization as an alternative to a volatile declaration

在本教程 (link) 中,关于 Java 的 volatile 声明据说 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 访问布尔值的机会。作为 volatile 声明的同步替代方案,作者的想法是什么?

// do stuff 部分将在同步块之外。例如,不是 doWork 被同步并具有 while (!shutdownRequested),您可能具有 while (!getShutDown()),其中 getShutDown 是 returns shutdownRequested 的同步方法。

这是它的一种工作方式:

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