volatile能保证有序性

在前面提到volatile关键字能禁止指令重排序,所以volatile能在一定程度上保证有序性。

  volatile关键字禁止指令重排序有两层意思:

  1)当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;

  2)在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。

  可能上面说的比较绕,举个简单的例子:

  1.  
    //x、y为非volatile变量
  2.  
    //flag为volatile变量
  3.  
     
  4.  
    x = 2; //语句1
  5.  
    y = 0; //语句2
  6.  
    flag = true; //语句3
  7.  
    x = 4; //语句4
  8.  
    y = -1; //语句5

由于flag变量为volatile变量,那么在进行指令重排序的过程的时候,不会将语句3放到语句1、语句2前面,也不会讲语句3放到语句4、语句5后面。但是要注意语句1和语句2的顺序、语句4和语句5的顺序是不作任何保证的。

  并且volatile关键字能保证,执行到语句3时,语句1和语句2必定是执行完毕了的,且语句1和语句2的执行结果对语句3、语句4、语句5是可见的。

  那么我们回到前面举的一个例子:

  1.  
    //线程1:
  2.  
    context = loadContext(); //语句1
  3.  
    inited = true; //语句2
  4.  
     
  5.  
    //线程2:
  6.  
    while(!inited ){
  7.  
    sleep()
  8.  
    }
  9.  
    doSomethingwithconfig(context);

前面举这个例子的时候,提到有可能语句2会在语句1之前执行,那么久可能导致context还没被初始化,而线程2中就使用未初始化的context去进行操作,导致程序出错。

  这里如果用volatile关键字对inited变量进行修饰,就不会出现这种问题了,因为当执行到语句2时,必定能保证context已经初始化完毕。

posted @ 2021-03-17 23:22  上台阶  阅读(416)  评论(0编辑  收藏  举报