V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
hadixlin
V2EX  ›  Java

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

  •  
  •   hadixlin · May 24, 2016 · 10989 views
    This topic created in 3633 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
        1
    xupefei  
       May 24, 2016
    这当然不是原子操作。这句话有几步:
    1. 在栈里新增一个指针 var 。
    2. 把指针指向 otherObjectValue 。
    zhuangzhuang1988
        2
    zhuangzhuang1988  
       May 24, 2016
    不是, 还得考虑内存重拍的影响..
    hadixlin
        3
    hadixlin  
    OP
       May 24, 2016 via Android
    @zhuangzhuang1988
    @xupefei

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

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