重排序

什么是重排序

  编译器和处理期为了提高程序的运行性能,对指令进行重新排序。

数据依赖性 as-if-serial

数据依赖性

1.写后读

2.读后写

3.写后写

指令重排序:

编译器重排序和处理器重排序

public class Demo {

    private int a;
    private boolean flag;

    public void writer(){
        a = 1;
        flag = true;

//
a , flag 没有数据依赖性,
//因此处理期会对这两行进行指令重排序
    }

    public void reader(){
         if(flag){
            int b = a +1;
            System.out.println(b);
        }

    }

}

happens-before

happen-before 是用来指定两个操作之间的执行顺序,提供跨线程的内存可见性。

在java内存模型中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作必然存在happens-before关系。

happen-before规则

程序顺序规则

监视器锁规则

volatile变量规则

传递性

Start规则

join规则

程序顺序规则:

单个线程中的每个操作,总是前一个操作happens-before于该线程中的任意后续操作

监视器规则

对同一个锁解锁,总是happen-before于随后对这个锁加锁

例: 1 happensbefore 2

 1 public class Demo {
 2     private Lock lock = new ReentrantLock();
 3 
 4     public void a(){
 5         lock.lock();
 6 
 7         lock.unlock(); //1.解锁
 8 
 9     }
10 
11     public void b(){
12         lock.lock(); //2.加锁
13 
14 
15         lock.unlock();
16 
17     }
18 }

volatile变量规则

对一个volatile域的写,happens-before于任意后续对这个volatile域的读

传递性

a happensbefore b

b happensbefore c

..

a happensbefore c

start规则

1  happensbefore  2

 1 public class Demo {
 2 
 3     public void a(){
 4         System.out.println("a");//1.启动另外一个线程
 5         new Thread(new Runnable() {
 6             @Override
 7             public void run() {
 8                 System.out.println("b");//2
 9             }
10         }).start();
11     }
12 
13 }

Join规则

与start规则相反

主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束

原文地址:https://www.cnblogs.com/quyangyang/p/11214556.html