下面的代码可以在多线程中工作吗? !boolean是java中的一个原子操作吗?!!boolean是java中的一个原子操作吗?
volatile boolean flag = true;
if (!flag){
do something
}
下面的代码可以在多线程中工作吗? !boolean是java中的一个原子操作吗?!!boolean是java中的一个原子操作吗?
volatile boolean flag = true;
if (!flag){
do something
}
是
!boolean
在java中的一个[n]原子操作吗?
号有三个操作位置:
线程切换可以发生在1和2之间,或者2和3之间,并且底层布尔值的值可以在任何时间或者在3或之后改变。
所以如果你想确定'做点什么'只发生如果flag
是同时错误,你将不得不同步,或使用信号量。
因为它标志着volatile
和值是一种原始的,这样保证了读取将始终是一致(不读部分初始化值的可能性)。
即使没有标记为volatile
,JVM也会始终以原子方式读取存储在32位或更小中的任何原始值。这是JLS 17.6中的语言要求。 (JLS 17.7允许对64位原始值进行“字符撕裂”,即long
和double
,它说这种行为是特定于实现的。实际上,在我所知的所有生产64位JVM实现中,甚至可以读取64位值始终是原子的。)
反转布尔操作的操作可能不是原子读取,但如果是这样的话,它将通过将布尔值复制到JVM指令堆栈工作,所以仍然不存在数据的可能性腐败(因为将值推入操作数栈是一个原子操作)。更有可能的是,JIT只会将您的if
条件反转并跳转到另一个分支,而不是实际反转布尔值。
当然,你仍然没有任何保证,在它被另一个线程改变之前,它不会立即读取该值,所以从字面上看,下一个指令可以开始执行,同时布尔值被另一个线程设置为true线。
即使是这样,一旦你进入if体内什么阻止它再次改变值呢?这与“not”期间的变化有何不同?为什么你的代码依赖于这是原子? – GManNickG
这是一个原子读取(无论是否为volatile),但“做某事”与前面的检查无关,除非您同步它。 – shmosel
为什么不使用AtomicBoolean对象? –