来自文档:
使用 volatile 变量可降低内存一致性错误的风险
但这意味着有时 volatile 变量不能正常工作?奇怪的是如何使用它 - 在我看来,这是非常糟糕的代码,有时工作有时不工作。我尝试谷歌,但没有找到易失性的示例内存一致性错误。你能推荐一个吗?
来自文档:
使用 volatile 变量可降低内存一致性错误的风险
但这意味着有时 volatile 变量不能正常工作?奇怪的是如何使用它 - 在我看来,这是非常糟糕的代码,有时工作有时不工作。我尝试谷歌,但没有找到易失性的示例内存一致性错误。你能推荐一个吗?
问题不在于volatile
工作不可靠。它总是按应有的方式工作。问题是它应该工作的方式有时不足以进行并发控制。如果volatile
在错误的情况下使用,仍然会出现内存一致性错误。
变量将volatile
始终将任何写入传播到所有线程。但是,假设您需要在各个线程之间增加变量。这样做(*):
volatile int mCounter;
// later, in some code that might be executed simultaneously on multiple threads:
mCounter++;
有可能会错过计数器增量。这是因为在mCounter
写入新值之前,每个线程都需要先读取 的值。在这两个步骤之间,另一个线程可能更改了mCounter
. 在这种情况下,您需要依赖synchronized
块而不是volatile
确保数据完整性。
有关volatile
vs.的更多信息synchronized
,我推荐Brian Goetz的文章管理波动性
(*)我意识到上面的实现会更好AtomicInteger
;这是一个人为的例子来说明一个观点。
易失性执行以下操作:
-它防止缓存线程中的值。
-它确保具有对象字段值副本的线程与内存中存在的主副本一致。
-确保数据直接写入内存并从内存本身读取。
## 但是 volatile 失败的情况:
-制作Non-Atomic statement Volatile
.
例如:
int count = 0;
count++; // Increment operator is Not Atomic in java
## 更好的选择:
1.最好遵循Brian's Rule
:
When ever we write a variable which is next to be read by another thread, or when we are reading a variable which is written just by another thread, it needs to be synchronized.
The shared fields must be made private, making the read and write methods/atomic statements synchronized.
2.第二个选项是使用AtomicInteger、AtomicLong、AtomicReference 等Atomic Classes
。
## 看到这个链接,我问过一个和你类似的问题: