简体   繁体   English

!boolean是Java中的原子操作吗?

[英]Is the !boolean a atomic operation in java?

Can the code below can work in multithreading? 下面的代码可以在多线程中工作吗? Is the !boolean a atomic operation in java? !boolean是Java中的原子操作吗?

volatile boolean flag = true;
if (!flag){
    do something
}

Because it's marked volatile and the value is a primitive, you are guaranteed that the read will always be consistent (no possibility of reading a partially-initialized value). 由于已将其标记为volatile且该值是原始值,因此可以确保读取始终是一致的(不可能读取部分初始化的值)。

Even if it weren't marked volatile , the JVM will always atomically read any primitive value that is stored in 32 bits or smaller. 即使未标记为volatile ,JVM也会始终自动读取存储在32位或更小值中的任何原始值。 This is a requirement of the language in JLS 17.6 . 这是JLS 17.6中语言的要求。 (JLS 17.7, which allows "word tearing" for 64-bit primitive values, namely long and double , says that this behavior is implementation-specific. In practice, on all production 64-bit JVM implementations I know of, reads of even 64-bit values are always atomic.) (JLS 17.7允许“字撕裂” 64位原始值(即longdouble )表示这种行为是特定于实现的。实际上,在我所知道的所有生产64位JVM实现中,甚至读取了64位。位值始终是原子的。)

The operation of inverting the boolean may not be atomic with the read, but if so it will work by copying the boolean value to the JVM instruction stack, so there's still no possibility of data corruption (since pushing the value onto the operand stack is an atomic operation). 读取布尔值的操作可能不是原子操作,但是如果是这样,则可以通过将布尔值复制到JVM指令堆栈来工作,因此仍然没有数据损坏的可能性(因为将值压入操作数堆栈是一种原子操作)。 More likely, the JIT will just invert your if condition and jump to the other branch rather than actually inverting the boolean value. JIT更有可能只是反转您的if条件并跳转到另一个分支,而不是实际反转布尔值。

Of course, you still don't have any guarantee you won't read the value immediately before it is changed by another thread, so literally the very next instruction may begin executing concurrently with the boolean being set to true by another thread. 当然,您仍然不能保证不会在另一个线程更改该值之前立即读取该值,因此从字面上看,下一条指令可能会在另一个线程将布尔值设置为true的同时开始执行。

Is the !boolean a[n] atomic operation in java? 是Java的!boolean a [n]原子操作吗?

No. There are three operations here: 否。这里有三个操作:

  1. Load the variable 加载变量
  2. Compare and branch. 比较并分支。
  3. 'do something'. '做一点事'。

A thread-switch can occur between 1 and 2, or 2 and 3, and the value of the underlying boolean can change at either time, or during 3, or after it. 线程切换可以发生在1和2之间,或者2和3之间,并且底层布尔值可以在任何时候,3或之后改变。

So if you want to be sure that 'do something' only happens if flag is simultaneously false, you will have to synchronize, or use a semaphore. 因此,如果要确保仅在flag 同时为 false时才执行“操作”,则必须进行同步或使用信号量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM