是JAVA中的原子操作 8 月 Questions & Answers 103 if (!var) {...} 上述内容是否会被扩展为类似的内容 将var的值加载到寄存器R中 设置R=!R 或者是只有一个操作的原子 加载值!输入寄存器R
# 1 楼答案 不,不可能 考虑以下两种情况: Thread 1 Thread 2 Load A to register ... ... Modify A Invert register ... 与 Thread 1 Thread 2 Atomically load !A ... to register ... Modify A 在这两种情况下,最终结果是相同的,寄存器包含不同于!A的值。负载反转操作的“原子”性质对结果绝对没有影响 如果这似乎会造成问题,您可能需要锁定。考虑在{{CD2}}上或在它所在的容器上进行同步。
# 2 楼答案 没有与逻辑not对应的字节码级操作。它通常会被编译为一个分支,尽管编译器有时会对此进行优化 例如,如果您编写类似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 楼答案
不,不可能
考虑以下两种情况:
与
在这两种情况下,最终结果是相同的,寄存器包含不同于
!A
的值。负载反转操作的“原子”性质对结果绝对没有影响如果这似乎会造成问题,您可能需要锁定。考虑在{{CD2}}上或在它所在的容器上进行同步。
# 2 楼答案
没有与逻辑not对应的字节码级操作。它通常会被编译为一个分支,尽管编译器有时会对此进行优化
例如,如果您编写类似
b = !a
的代码,它通常会被编译成然而在你提到的
if (!var)
的特殊情况下,这是没有必要的。这是因为if指令在正则和反向条件下都有变体,即编译器不会实际对var
求反,而是使用ifne
指令,而不是通常的ifeq
编辑:以上是如何将代码编译成字节码。就同步而言,出于实际目的,它是原子的。由于代码是纯本地的,因此通常无法观察副作用,也无法让计算干扰其他线程。请注意,即使加载一个未同步的字段,该值也会变成一个中间值(即“寄存器”),并对该值执行操作,而该值不会在线程之间共享。除了读和写之外,没有任何操作直接发生在字段上
这样说,因为代码涉及多个字节码指令,所以可以在中间停止调试器。在这种情况下,您可以观察中间状态,尽管它对其他线程仍然没有影响