title: 指令重排序
date: 2017-12-25 12:50:17
categories:
- concurrent
tags:
- Java
- concurrent
- JDK源码
在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件:
- 在单线程环境下不能改变程序运行的结果;
- 存在数据依赖关系的不允许重排序
as-if-serial语义
as-if-serial语义的意思是,所有的操作均可以为了优化而被重排序,但是你必须要保证重排序后执行的结果不能被改变,编译器、runtime、处理器都必须遵守as-if-serial语义。注意as-if-serial只保证单线程环境,多线程环境下无效。
多线程下 重排序的影响
public class RecordExample2 {
int a = 0;
boolean flag = false;
/**
* A线程执行
*/
public void writer(){
a = 1; // 1
flag = true; // 2
}
/**
* B线程执行
*/
public void read(){
if(flag){ // 3
int i = a + a; // 4
}
}
}
A线程执行writer(),线程B执行read(),线程B在执行时能否读到 a = 1 呢?答案是不一定. 这就是因为操作1 操作2之间并没有数据依赖,如果想产生依赖的话,就加上volatile把。