以下代码可以在多线程中工作吗? !boolean是java中的原子操作吗?
volatile boolean flag = true;
if (!flag){
do something
}
答案 0 :(得分:1)
因为它标记为volatile
并且值是基元,所以保证读取始终是一致的(不可能读取部分初始化的值)。
即使它没有被标记为volatile
,JVM也将始终以原子方式读取以32位或更小的比特存储的任何原始值。这是JLS 17.6中语言的要求。 (JLS 17.7,允许"单词撕裂"对于64位原始值,即long
和double
,表示此行为是特定于实现的。实际上,在所有生产中我所知道的64位JVM实现,甚至64位值的读取总是原子的。)
反转布尔值的操作在读取时可能不是原子操作,但如果是这样,它将通过将布尔值复制到JVM指令堆栈来工作,因此仍然不存在数据损坏的可能性(因为推送值到操作数堆栈上是一个原子操作)。更有可能的是,JIT只会反转你的if
条件并跳转到另一个分支而不是实际反转布尔值。
当然,你仍然没有任何保证你不会在另一个线程更改之前立即读取该值,因此字面意思是下一条指令可能会在布尔设置为另一个线程是真的。
答案 1 :(得分:1)
java中的
!boolean
a [n]原子操作是什么?
没有。这里有三个操作:
线程切换可以在1和2之间,或2和3之间发生,并且底层布尔值可以在任何时间,3或3之间发生变化。
因此,如果您希望确保只有当flag
同时为false时才会“执行某些操作”,则必须同步或使用信号量。