对象唤醒条件变量是否应该加上volatile修饰符?

Should the volatile modifier be added to the object wake-up condition variable?

请检查下面的示例代码:

private volatile int fActiveTestDeathCount;

synchronized void waitUntilFinished() {
        while (fActiveTestDeathCount < testCount()) {
            try {
                wait();
            } catch (InterruptedException e) {
                return; // ignore
            }
        }
    }

上面的代码可以正常运行,很好理解,但是为什么下面的代码也可以正常运行呢?

private int fActiveTestDeathCount;

synchronized void waitUntilFinished() {
    while (fActiveTestDeathCount < testCount()) {
        ...
    }
}

我认为在多线程执行环境下,每个线程都会复制fActiveTestDeathCount变量。如果没有额外的volatile修饰符,这个变量对其他线程是不可见的,程序应该就不能运行了,但事实并非如此

我尝试分析是不是线程被唤醒后,会自动使线程工作内存中的变量失效,然后从主内存同步数据?但是这需要内存屏障的支持,让我有点疑惑。

这里volatile既不是必需的也不充分。

为什么还不够?因为它不会阻止一个线程在它被另一个线程修改之前立即检查 fActiveTestDeathCount,然后不可撤销地决定 wait 以检查它检查后立即发生的事情。

为什么不需要?因为 synchronized 已经在访问 fActiveTestDeathCount.

的任何两个线程之间建立了“发生在之前”的关系

wait 的重点是提供一个原子“解锁并等待”操作来精确解决这个竞争条件。