java - 可变关键字线程安全
问题描述
在谷歌上搜索了很多之后,我发现了 volatile 关键字的多个定义。
概念一:
一些网站说,它是线程安全的,因为线程作用于存储 volatile 关键字的主内存并对其进行修改,而不会将其拉到线程堆栈空间。
概念二:
有人说,它不是线程安全的,因为它会导致线程竞争条件。As ,线程将 volatile 变量拉入堆栈空间,对其进行修改并立即将其放回主内存。但是,在另一个线程之间可以来对 volatile 变量采取行动并采取行动。所以,这样,一些价值就会丢失。
哪个概念是正确的?
解决方案
volatile
本身既不是线程安全的,也不是非线程安全的。
volatile
保证单个字段的原子性,因此它可以用于单线程安全读取或单线程安全写入。
但是,如果您想要执行由读取后跟写入组成的线程安全操作(作为一个整体来理解),volatile
那么这里单独不提供线程安全性,因为volatile
仅保证单个操作(读取或写入)的原子性。
总结一下:
- 如果你有一个字段并且你想确保如果一个线程写入它,其他线程可以立即读取写入的值 -
volatile
就足够了(没有volatile
,其他线程甚至可能永远看不到写入的值) - 如果您有一个需要先读取然后再写入的字段(基于您刚刚读取的值,因此在这之间可能不会对该值进行任何操作),
volatile
这还不够;相反,您可以使用: