JMM-有序性

JMM-有序性

1.概念

JVM 会在不影响正确性的前提下,可以调整语句的执行顺序,思考下面一段代码。

在这里插入图片描述
可以看到,至于是先执行 i 还是 先执行 j ,对最终的结果不会产生影响。所以,上面代码真正执行时,既可以是

在这里插入图片描述
或者
在这里插入图片描述
这种特性称之为『指令重排』。
多线程下『指令重排』会影响正确性

2.指令重排原理

2.1 关于CPU的几个概念

  • Clock Cycle Time
    主频的概念大家接触的比较多,而 CPU 的 Clock Cycle Time(时钟周期时间),等于主频的倒数,意思是 CPU 能够识别的最小时间单位,比如说 4G 主频的 CPU 的 Clock Cycle Time 就是 0.25 ns,作为对比,我们墙上挂钟的Cycle Time 是 1s。
    例如,运行一条加法指令一般需要一个时钟周期时间

  • CPI
    有的指令需要更多的时钟周期时间,所以引出了 CPI (Cycles Per Instruction)指令平均时钟周期数

  • IPC
    IPC(Instruction Per Clock Cycle) 即 CPI 的倒数,表示每个时钟周期能够运行的指令数

  • CPU 执行时间
    程序的 CPU 执行时间,即我们前面提到的 user + system 时间,可以用下面的公式来表示:

程序 CPU 执行时间 = 指令数 * CPI * Clock Cycle Time

2.2 指令重排优化

事实上,现代处理器会设计为一个时钟周期完成一条执行时间最长的 CPU 指令。为什么这么做呢?可以想到指令还可以再划分成一个个更小的阶段,例如,每条指令都可以分为:
【取指令 - 指令译码 - 执行指令 - 内存访问 - 数据写回】
这 5 个阶段

在这里插入图片描述

在不改变程序结果的前提下,这些指令的各个阶段可以通过重排序和组合来实现指令级并行。指令重排的前提是,重排指令不能影响结果,例如

在这里插入图片描述

2.3 支持流水线的处理器

现代 CPU 支持多级指令流水线,例如支持同时执行 取指令 - 指令译码 - 执行指令 - 内存访问 - 数据写回 的处理器,就可以称之为五级指令流水线。

这时 CPU 可以在一个时钟周期内,同时运行五条指令的不同阶段(相当于一条执行时间最长的复杂指令),IPC = 1,

本质上,流水线技术并不能缩短单条指令的执行时间,但它变相地提高了指令地吞吐率。

在这里插入图片描述

2.4指令重排导致的问题

在这里插入图片描述
【情况1】先执行线程1,再执行线程2,r1=1
【情况2】先执行线程2,再执行线程1,r1=4
【情况3】先执行2,但发生指令重排,先执行ready=true,r1=0

情况3可以使用并发压测工具复现:
借助 java 并发压测工具 jcstress
https://wiki.openjdk.java.net/display/CodeTools/jcstress

mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=org.openjdk.jcstress -
DarchetypeArtifactId=jcstress-java-test-archetype -DarchetypeVersion=0.5 -DgroupId=cn.itcast -
DartifactId=ordering -Dversion=1.0

3.volatile原理

volatile 的底

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值