美文网首页java进阶干货程序员
R大有时会颠覆你Java的认知

R大有时会颠覆你Java的认知

作者: 美团Java | 来源:发表于2018-03-22 15:00 被阅读2660次

    关于volatile变量的内存可见性,我在JVM群中抛出了一个问题,然后我的一些认知就被颠覆了。

    问题

    请教一个问题,a,b,c三个变量,其中c是volatile的,a,b是普通变量, a = 1, b = 2, c = 3, c写入之后,a,b的值也会被刷入缓存吗,还是c写入之前所有在cpu缓存的数据都会被刷入内存,还是只刷入和c在同一个缓存行的数据?

    一开始,我的认知是后者,只刷入同一个缓存行的数据。

    R大问答

    你们要按happens before来考虑这种问题,不要整天无谓想着擦车(cache),Java的修正过的内存模型其实基本点很简单,同一线程内的副作用按程序顺序发生,所以a、b、c的赋值如果是在同一线程内按这个顺序写的,实际执行就要按照这个顺序发生(至少表象上要按照这个顺序;在程序无法感知顺序差异时可以作弊)

    这样就是a赋值happens before b赋值,b赋值happens before c赋值,而不同线程之间的操作则是没有happens before关系的,除非有volatile或者synchronized等带有跨线程happen before关系的操作。不同线程之间的非volatile、非synchronized操作直接要想有传递的happens before关系的话,中间就肯定得有能产生happens before关系的volatile或者synchronized操作。

    什么寄存器啊、缓存啊啥的不必扯进来。

    我的反应

    哦~~~问号脸。。。

    R大继续解释

    JVM实现的时候是要把这些概念映射下去的(这里的概念应该就是happens before),但是当你在思考高层程序语义的时候却拿不合适的低层语义去解释就很别扭,映射下去的办法就是先有高层语义,然后看具体硬件上提供了哪些原语,然后再去实现。例如说在SPARC上它默认是TSO(total store order)的,在上面需要手工做的同步操作就很简单。

    晓铭大大的总结

    JIT的时候会去查操作数的属性,如果是volatile会在读写操作附近生成barrier的中间表示,最终barrier中间表示会变成什么指令,那要根据具体的机器,Memory consistency是一个spec,各种硬件系统包括cache都是实现的细节。

    总结

    总结起来,我这个问题问的不好,没水准,问题直接从jmm跳到了硬件具体实现,中间还隔着一层硬件的memory model。

    所以缓存到底怎么刷,不同的CPU、不同厂商、不同型号实现可能都不一样,一个人想了解所有似乎是个不可能的任务,也不实用,只需要搞清楚JMM层面的东西就OK,管它到底怎么刷。

    推广

    知识星球可以干什么?
    1、【分享】高质量的技术文章
    2、【沉淀】「战狼群」高质量问题&解决方案
    3、【成长】项目经验,生活随笔,学习心得
    4、【复盘】实战经验,故障总结
    5、【面经】面试经验分享与总结
    6、【推荐】技术书籍,岗位招聘

    相关文章

      网友评论

      • 68号小喇叭:volatile变量写会将之前所有变量的操作都会刷新回主存,其他core的缓存失效,不管这些变量是否volatile,也就是只要操作在volatile写之前,另一个线程的volatile读发生在volatile写之后的话,这些操作读线程也能看到,可搜索 你真的懂volatile吗:sweat_smile:
      • 99e1f97b5d71:volatile关键字能禁止指令重排序,volatile关键字禁止指令重排序有两层意思:

          1)当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;

          2)在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。
        人在码途:@Am_11e8 你好,第二条能详细解释下么?没明白,谢谢
      • wyn_做自己:晕乎乎:sweat:
      • 科学Jia:所以说,在一个线程里的a, b, c是都会被刷入主存里了?如果不是一个线程,且没happen-before关系,就不一定了,对吧?
      • amourling:好想去你们的技术群:sweat_smile:
      • 蓝风9:我图都保存了 :smirk:

      本文标题:R大有时会颠覆你Java的认知

      本文链接:https://www.haomeiwen.com/subject/lfitqftx.html