if (!var) {...}
上述内容是否会用于
之类的内容或者只有一次操作的原子
答案 0 :(得分:4)
没有与逻辑非对应的字节码级别操作。它通常会被编译为分支,尽管编译器有时可以优化它。
例如,如果您编写类似b = !a
的代码,通常会将其编译为
iload_0 ; load a
ifeq Lelse
iconst_0
goto Lend
Lelse:
iconst_1
Lend:
istore_1 ; store into B
然而在您提到的if (!var)
的特殊情况下,这不是必需的。这是因为if指令具有常规和反向条件的变体,即不是实际否定var
,编译器只使用ifne
指令而不是通常的ifeq
。
编辑:以上是代码如何编译成字节码。就同步而言,它是实用的原子。由于代码纯粹是局部的,因此通常无法观察副作用或计算干扰其他线程。请注意,即使您加载了一个非同步字段,该值也会成为一个中间值(即“寄存器”),并且该值会发生操作,而这些值不会在线程之间共享。除了读取和写入之外的字段上不会直接执行任何操作。
话虽如此,由于代码涉及多个字节码指令,您可以在其中间停止调试器。在这种情况下,您可以观察中间状态,尽管它仍然对其他线程没有影响。
答案 1 :(得分:1)
没有。它不可能。
考虑以下两种情况:
Thread 1 Thread 2
-------- --------
Load A to register ...
... Modify A
Invert register ...
VS
Thread 1 Thread 2
-------- --------
Atomically load !A ...
to register
... Modify A
最终结果是相同的 - 在这两种情况下,寄存器包含的值都不同于!A
。负荷反转操作的“原子”性质对结果完全没有影响。
如果这似乎可能造成问题,您可能需要锁定。考虑在A
上或在其所在的容器上进行同步。