使用volatile关键字时内存一致性错误的示例?

use*_*818 8 java memory multithreading consistency volatile

来自docs:

使用volatile变量可降低内存一致性错误的风险

但这意味着有时候volatile变量不能正常工作?奇怪的是如何使用 - 我认为这是非常糟糕的代码,有时有时不工作.我试过谷歌,但没有找到与volatile有关的示例内存一致性错误.你能提出一个吗?

Ted*_*opp 10

问题不在于volatile工作不可靠.它总是以它应该工作的方式工作.问题是它应该工作的方式有时不适合并发控制.如果您volatile在错误的情况下使用,仍然可能会出现内存一致性错误.

一个volatile变量总会有传播到所有线程任何写入.但是,假设您需要在各种线程中增加变量.这样做(*):

volatile int mCounter;

// later, in some code that might be executed simultaneously on multiple threads:
mCounter++;
Run Code Online (Sandbox Code Playgroud)

有可能错过计数器增量.这是因为在mCounter写入新值之前,每个线程需要首先读取值.在这两个步骤之间,另一个线程可能已经改变了它的值mCounter.在这种情况下,您需要依赖synchronized块而不是volatile确保数据完整性.

有关volatilevs.的更多信息synchronized,我推荐Brian Goetz 撰写的管理易变性文章

(*)我意识到上面会更好地实现AtomicInteger; 这是一个人为的例子来说明一个观点.