简体   繁体   English

是! JAVA中的原子操作

[英]Is ! operation atomic in JAVA

if (!var) {...}

Does the above get expended into something like 以上是否扩展为类似

  • load value of var into register R 将var的值加载到寄存器R中
  • set R = !R 设置R =!R

Or its atomic where there is only a single operation 或只有一个操作的原子

  • load value of !var into register R 将!var的值加载到寄存器R中

There is no bytecode level operation corresponding to logical not. 没有对应于逻辑非的字节码级操作。 It will typically get compiled as a branch, though the compiler can sometimes optimize that away. 它通常将被编译为一个分支,尽管编译器有时可以对其进行优化。

For example, if you write code like b = !a , it would typically get compiled into something along the lines of 例如,如果您编写类似b = !a代码,则通常会将其编译成类似以下内容的代码:

iload_0 ; load a
ifeq Lelse
iconst_0
goto Lend

Lelse:
iconst_1

Lend:
istore_1 ; store into B

However in the special case of if (!var) that you mentioned, this is not necessary. 但是 ,在您提到的if (!var)的特殊情况下,这不是必需的。 This is because the if instructions have variants for both regular and reversed conditions, ie instead of actually negating var , the compiler would just use the ifne instruction instead of the usual ifeq . 这是因为if指令对正则和反向条件都有变体,即,而不是实际否定var ,编译器将只使用ifne指令而不是通常的ifeq

Edit: The above is how the code is compiled into bytecode. 编辑:上面是如何将代码编译为字节码。 As far as synchronization goes, it is atomic for practical purposes. 就同​​步而言,出于实用目的,它是原子的。 Since the code is purely local, there is ordinarily no way to observe side effects or for the calculation to interfere with other threads. 由于代码是纯本地代码,因此通常没有办法观察副作用或使计算干扰其他线程。 Note that even if you load an unsynchronized field, the value becomes an intermediate value (ie a "register") and operations occur on that value, which is not shared among threads. 请注意,即使加载了未同步的字段,该值也将成为中间值(即“寄存器”),并且会对该值进行操作,该值不会在线程之间共享。 No operation occurs directly on a field other than reads and writes. 除了读取和写入之外,没有任何其他操作直接在字段上发生。

That being said, since the code involves multiple bytecode instructions, you could stop a debugger in the middle of it. 话虽如此,由于代码涉及多个字节码指令,因此您可以在其中停止调试器。 In that case, you could observe the intermediate state, although it would still have no effect on other threads. 在那种情况下,您可以观察到中间状态,尽管它对其他线程仍然没有影响。

No. It can't be. 不,不可能。

Consider the following two scenarios: 请考虑以下两种情况:

Thread 1                Thread 2
--------                --------
Load A to register      ...
...                     Modify A
Invert register         ...

vs.

Thread 1                Thread 2
--------                --------
Atomically load !A      ...
    to register
...                     Modify A

The end result is the same -- in both cases, the register contains a value different from !A . 最终结果是相同的-在两种情况下,寄存器包含的值都与!A不同。 The "atomic" nature of the load-inverted operation had absolutely no effect on the outcome. 负载反转操作的“原子”性质对结果绝对没有影响。

If this seems like it could pose a problem, you probably need locking. 如果这看起来可能会带来问题,则可能需要锁定。 Consider synchronizing on A , or on the container that it lives in. 考虑在A或它所在的容器上进行同步。

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

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