hadixlin
V2EX  ›  Java

Java 中对引用类型的变量赋值是原子操作吗?

  •  
  •   hadixlin · May 24, 2016 · 11561 views
    This topic created in 3817 days ago, the information mentioned may be changed or developed.

    看过一些资料说对原始类型不包括(long,double)变量进行赋值是原子操作,但是没有找到资料对引用类型的变量的赋值操作的原子性进行说明.

    例如 Object var = otherObjectValue; 这是原子操作吗?依据是什么.

    Supplement 1  ·  May 24, 2016
    只想确认这个操作是不是原子的,不讨论线程安全的问题
    16 replies  •  2016-05-24 23:09:55 +08:00
    xupefei
    xupefei
    May 24, 2016
    1
    这当然不是原子操作。这句话有几步:
    1. 在栈里新增一个指针 var 。
    2. 把指针指向 otherObjectValue 。
    zhuangzhuang1988
    zhuangzhuang1988
    May 24, 2016
    2
    不是, 还得考虑内存重拍的影响..
    hadixlin
    hadixlin
    OP
    May 24, 2016 via Android
    3
    @zhuangzhuang1988
    @xupefei

    请问有相关资料可以查阅吗?
    zhunimagebice
    zhunimagebice
    May 24, 2016 via Android
    4
    这不是赋值吧?
    hadixlin
    hadixlin
    OP
    May 24, 2016 via Android
    5
    @zhunimagebice 你觉得不是赋值是什么
    zhunimagebice
    zhunimagebice
    May 24, 2016 via Android
    7
    @hadixlin 这是 new 加 assign 吧,光是 assign 应该是原子操作(去掉 var )
    zhunimagebice
    zhunimagebice
    May 24, 2016 via Android
    8
    去掉 Object
    hadixlin
    hadixlin
    OP
    May 24, 2016
    9
    @zhunimagebice 参考依据是什么?
    hadixlin
    hadixlin
    OP
    May 24, 2016
    10
    @zhuangzhuang1988 我没翻到哪个章节有具体说明,请指教.
    suikator
    suikator
    May 24, 2016 via Android
    11
    一楼说的很清楚了,虽然分开每一步都是原子操作,但是合并起来就不是原子操作了
    sagnitude
    sagnitude
    May 24, 2016❤️2
    12
    我认为是原子的

    1. 向 reference 赋值是原子的(obj = otherObjectValue):
    https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7

    2. 声明立刻赋值和赋值是等价的(Object var = objValue; 和 var = objValue 等价)
    ```
    K k = source;
    ```
    和
    ```
    K k;
    k = source;
    ```
    编译出的字节码是一样的;(使用 javap -c):
    https://gist.github.com/sagnitude/03d0cc5a9f244b61f47e89e59f485587

    由 1 和 2 ,声明一个 reference 并立刻赋值( Object obj = otherObjectValue )是原子的。


    @xupefei 在字节码里是 2 句指令 `aload`和`astore`,但是这两句根据上面提到的 JLS ,原子性是有保证的:

    1. k = source 等价于
    ```
    8: aload_1 // source 压栈
    9: astore_2 // source 出栈给 k
    ```

    2. k = source 是 reference 赋值
    3. reference 赋值根据 JLS ,是原子的
    => 用于 reference 赋值的`aload + astore`是原子的
    wizardforcel
    wizardforcel
    May 24, 2016 via Android
    13
    我认为分开每句都是,但是合起来不是。
    hadixlin
    hadixlin
    OP
    May 24, 2016
    14
    @sagnitude 理据充分,谢谢.
    final7genesis
    final7genesis
    May 24, 2016
    15
    我感觉是原子操作, 但也会出现线程不安全的情况;
    例子 http://stackoverflow.com/questions/5307003/java-multi-threading-atomic-reference-assignment
    原因处理器优化执行造成的非线性执行 http://www.infoq.com/cn/articles/java-memory-model-2
    hadixlin
    hadixlin
    OP
    May 24, 2016 via Android
    16
    @final7genesis 只讨论原子性,不考虑线程安全问题
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3027 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 11:43 · PVG 19:43 · LAX 03:43 · JFK 06:43
    ♥ Do have faith in what you're doing.