Java并发编程的艺术(五)重排序
1、重排序:指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。
2、数据依赖性:两个操作访问同一个变量,且者两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性。
(1)分类:写后读、写后写、读后写。
(2)编译器和处理器在重排序时,会遵守数据依赖性,不会改变存在数据依赖关系的两个操作的执行顺序。
(3)数据依赖性只针对单个处理器中执行的指令序列和单个线程中执行的操作。
3、as-if-serial:不管怎么重排序,(单线程)程序的执行结果不能被改变,多线程则执行结果可能会被改变。
4、volatile的重排序规则:
(1)volatile写之前的操作不会被编译器重排序到volatile写之后。
(2)volatile读之后的操作不会被编译器重排序到volatile读之前。
(3)第一个操作是volatile写,第二个操作是volatile读时,不能重排序。
5、final域的重排序规则:
(1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。
(2)初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序。