V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hadixlin
V2EX  ›  Java

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

  •  
  •   hadixlin · 2016-05-24 00:00:04 +08:00 · 10184 次点击
    这是一个创建于 2887 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    请问有相关资料可以查阅吗?
    zhunimagebice
        4
    zhunimagebice  
       2016-05-24 08:54:48 +08:00 via Android
    这不是赋值吧?
    hadixlin
        5
    hadixlin  
    OP
       2016-05-24 09:35:23 +08:00 via Android
    @zhunimagebice 你觉得不是赋值是什么
    zhuangzhuang1988
        6
    zhuangzhuang1988  
       2016-05-24 09:49:21 +08:00
    zhunimagebice
        7
    zhunimagebice  
       2016-05-24 09:56:11 +08:00 via Android
    @hadixlin 这是 new 加 assign 吧,光是 assign 应该是原子操作(去掉 var )
    zhunimagebice
        8
    zhunimagebice  
       2016-05-24 09:56:44 +08:00 via Android
    去掉 Object
    hadixlin
        9
    hadixlin  
    OP
       2016-05-24 10:23:25 +08:00
    @zhunimagebice 参考依据是什么?
    hadixlin
        10
    hadixlin  
    OP
       2016-05-24 10:30:51 +08:00
    @zhuangzhuang1988 我没翻到哪个章节有具体说明,请指教.
    suikator
        11
    suikator  
       2016-05-24 10:37:30 +08:00 via Android
    一楼说的很清楚了,虽然分开每一步都是原子操作,但是合并起来就不是原子操作了
    sagnitude
        12
    sagnitude  
       2016-05-24 11:14:02 +08:00   ❤️ 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  
       2016-05-24 11:31:30 +08:00 via Android
    我认为分开每句都是,但是合起来不是。
    hadixlin
        14
    hadixlin  
    OP
       2016-05-24 11:39:40 +08:00
    @sagnitude 理据充分,谢谢.
    final7genesis
        15
    final7genesis  
       2016-05-24 16:30:57 +08:00
    我感觉是原子操作, 但也会出现线程不安全的情况;
    例子 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
       2016-05-24 23:09:55 +08:00 via Android
    @final7genesis 只讨论原子性,不考虑线程安全问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5341 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 09:13 · PVG 17:13 · LAX 02:13 · JFK 05:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.