博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java并发--volatile内存语义的实现
阅读量:2445 次
发布时间:2019-05-10

本文共 1243 字,大约阅读时间需要 4 分钟。

volatile内存语义的实现

为了实现volatile内存语义,JMM会分别读与写这两种类型的重排序类型。JMM针对编译器制定的volatile重排序规则表如下:

在这里插入图片描述

举例来说,第三行最后一个单元格的意思是:在程序中,当第一个操作为普通变量的读或写时,如果第二个操作为volatile写,则编译器不能重排序这两个操作。

从表我们可以看出:

  • 当第二个操作是volatile写时,不管第一个操作是什么,都不能重排序。这个规则确保volatile写之前的操作不会被编译器重排序到volatile写之后。
  • 当第一个操作是volatile读时,不管第二个操作是什么,都不能重排序。这个规则确保volatile读之后的操作不会被编译器重排序到volatile读之前。
  • 当第一个操作是volatile写,第二个操作是volatile读时,不能重排序。

为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。 对于编译器来说,发现一个最优布置来最小化插入屏障的总数几乎不可能。为此,JMM采取保守策略。下面是基于保守策略的JMM内存屏障插入策略。

  • 在每个volatile写操作的前面插入一个StoreStore屏障。
  • 在每个volatile写操作的后面插入一个StoreLoad屏障。
  • 在每个volatile读操作的后面插入一个LoadLoad屏障。
  • 在每个volatile读操作的后面插入一个LoadStore屏障。

上述内存屏障插入策略非常保守,但它可以保证在任意处理器平台,任意的程序中都能得到正确的volatile内存语义。

保守策略下,volatile写插入内存屏障后生成的指令序列示意图

在这里插入图片描述

保守策略下,volatile读插入内存屏障后生成的指令序列示意图

在这里插入图片描述

在实际执行时,只要不改变volatile写-读的内存语义,编译器可以根据具体情况省略不必要的屏障。下面通过具体的示例代码进行说明。

在这里插入图片描述
在这里插入图片描述

注意,最后的StoreLoad屏障不能省略。因为第二个volatile写之后,方法立即return。此时编译器可能无法准确断定后面是否会有volatile读或写,为了安全起见,编译器通常会在这里插入一个StoreLoad屏障。

上面的优化针对任意处理器平台,由于不同的处理器有不同“松紧度”的处理器内存模型,内存屏障的插入还可以根据具体的处理器内存模型继续优化。以X86处理器为例,图中除最后的StoreLoad屏障外,其他的屏障都会被省略。

因为X86处理器仅会对写-读操作做重排序。X86不会对读-读、读-写和写-写操作做重排序,因此在X86处理器中会省略掉这3种操作类型对应的内存屏障。在X86中,JMM仅需在volatile写后面插入一个StoreLoad屏障即可正确实现volatile写-读的内存语义。这意味着在X86处理器中,volatile写的开销比volatile读的开销会大很多(因为执行StoreLoad屏障开销会比较大)。

在这里插入图片描述

转载地址:http://aypqb.baihongyu.com/

你可能感兴趣的文章
karma jasmine_使用Jasmine和Karma测试AngularJS(第2部分)
查看>>
了解和使用Laravel雄辩的宏
查看>>
slim3框架 教程_SLIM 3入门,PHP微框架
查看>>
swagger使用api_使用Swagger记录您已经存在的API
查看>>
vue.js js请求加密_使用Vue.js构建一个加密货币比较网站
查看>>
angular2 cli_将Angular CLI用于更快的Angular v2 +项目
查看>>
从JavaScript到TypeScript Pt。 I:类型和变量
查看>>
python 微框架_Flask入门,Python微框架
查看>>
webpack 入门_Webpack入门:模块捆绑魔术
查看>>
使用Python和Flask构建CRUD Web应用-第二部分
查看>>
laravel scout_使用Laravel Scout和Algolia实现地理搜索
查看>>
使用Python和Flask构建CRUD Web应用-第一部分
查看>>
渐进式web应用程序_渐进式Web应用程序终极指南
查看>>
使用Angular和Docker Compose创建MEAN应用
查看>>
构建meteor应用程序_在5分钟内构建客户服务消息传递应用程序
查看>>
使用React&Redux打造书店I:React Redux Flow
查看>>
使用Chrome DevTools断点调试JavaScript
查看>>
polymer ajax_使用Polymer构建真实的电池状态Web组件
查看>>
Snipcart与WordPress的完全电子商务集成
查看>>
使用Vue.js处理Laravel验证错误消息
查看>>