Java 指令重排
Posted feshfans
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 指令重排相关的知识,希望对你有一定的参考价值。
Java 指令重排
package com.feshfans;
/**
* 用来演示指令重排
* 指令重排会发生在两个阶段:
* 1. 编译期(jvm 加载字节码时)
* 2. cpu 执行期
* 但对于单线程来说,不管发生怎样的重排,都必须保持与源代码一致的输出结果(As-If-Serial).
* 上述规则保证了单线程的执行结果总是与预期一致,但在多线程的情况,就会出现与预期不一致的情况,
* 而导致这一情况发生的原因,正是指令重排
*
*/
public class InstructionReOrder
static Integer a = 0;
static Integer b = 0;
static Integer x = 0;
static Integer y = 0;
private void showReOrder() throws InterruptedException
for(int i=0;i<Integer.MAX_VALUE;i++)
Thread t1 = new Thread(new Runnable()
@Override
public void run()
// 有可能发生重排,即 先执行 x = b,再执行 a = 1
a = 1;
x = b;
);
Thread t2= new Thread(new Runnable()
@Override
public void run()
// 有可能发生重排,即先执行 y = a,再执行 b = 1;
b = 1;
y = a;
);
t1.start();
t2.start();
t1.join();
t2.join();
/**
* 如果没有指令重排,输出的可以结果为:(0,1)(1,1)(1,0)
* 但实际上有可能会输出(0,0)
*/
System.out.println("第 "+ i + "次,x="+x +", y="+y);
if(x == 0 && y == 0)
break;
a = b = 0;
x = y = 0;
public static void main(String[] args)
InstructionReOrder reOrder = new InstructionReOrder();
try
reOrder.showReOrder();
catch (InterruptedException e)
e.printStackTrace();
输出结果如下:
从上图中可以看出,执行到第 65456 次时,发生了指令重排
以上是关于Java 指令重排的主要内容,如果未能解决你的问题,请参考以下文章