volatile的指令重排序理解

volatile的实现逻辑涉及的是指令重排序原理,下面对该关键字不同情况下的指令重排序做点简单的分析.

先上一个表格列出各种重排序规则.

对上面这个表格的分析如下:

1.两个操作都是普通读和写,没有volatile要求,可以重排序
2.如果重排序,操作2(volatile读主内存)排在操作1的读和写之前:
  2-1. 操作2(volatile读主内存) -> 操作1(普通读本地内存), 两个操作并行执行互不干扰,所以重排序无影响
  2-2. 操作2(volatile读主内存) -> 操作1(普通写本地内存), 两个操作并行执行互不干扰,所以重排序无影响
3.如果重排序,操作2(volatile写主内存)排在操作1的读和写之前:
  3-1. 操作2(volatile写主内存) -> 操作1(普通读本地内存), 操作1读本地内存和操作2不干扰,
       但是操作1写本地内存后会在后面刷新主内存,操作2(volatile写主内存)的结果被覆盖,导致程序的执行结果不正确,所以不能重排序
  3-2. 操作2(volatile写主内存) -> 操作1(普通写本地内存), 和3-1类似,不能重排序、
4.操作1(volatile读主内存)
  4-1. 操作2普通读 被重排序到 操作1(volatile读主内存) 之前,对执行结果无影响,可以重排序
  4-2. 操作2普通写 如果被重排序到 操作1(volatile读主内存) 之前,并且刷新了主内存数据,则可能导致操作1(volatile读主内存)读到错误数据,所以不能重排序指令
5.操作1和2都是volatile,不能重排序
6.操作1和2都是volatile,不能重排序
7.与2类似,操作2是普通读和写
  7-1.操作2普通读,如果重排序到操作1(volatile写主内存)之前,因为读的是本地数据,与操作1无关,可以重排序
  7-2.操作2普通写,如果重排序到操作1(volatile写主内存)之前,即便主存数据后面被操作1修改了,因为写的是本地内存,而且没有volatile要求,所以对执行结果无影响,可以重排序
8.操作1和2都是volatile,不能重排序
9.操作1和2都是volatile,不能重排序

总结:
1.两个操作都有volatile要求的,一定不能重排序指令
2.后面如果是volatile写操作,则即便前面是普通写操作,为了保证主存数据是后面操作的结果,所以不能重排序
3.前面如果是volatile读操作,因为后面的普通写操作可能会刷新主存,为了保证百分百执行结果的正确,则也不能重排序
4.其他情况可以重排序指令

没有更多推荐了,返回首页