volatile关键字是否真的理解了,就看怎么回答这个问题。

问题:

       a,b,c三个变量,其中c是volatile的,a,b是普通变量, a = 1, b = 2, c = 3, c写入之后,a,b的值也会被刷入缓存吗,还是c写入之前所有在cpu缓存的数据都会被刷入内存,还是只刷入和c在同一个缓存行的数据?

答:

       要按happens before来考虑这种问题,不要想着(cache),Java的修正过的内存模型其实基本点很简单,同一线程内的副作用按程序顺序发生,所以a、b、c的赋值如果是在同一线程内按这个顺序写的,实际执行就要按照这个顺序发生(至少表象上要按照这个顺序;在程序无法感知顺序差异时可以作弊)
       这样就是a赋值happens before b赋值,b赋值happens before c赋值,而不同线程之间的操作则是没有happens before关系的,除非有volatile或者synchronized等带有跨线程happen before关系的操作。不同线程之间的非volatile、非synchronized操作直接要想有传递的happens before关系的话,中间就肯定得有能产生happens before关系的volatile或者synchronized操作。

扩展:

         volatile变量写会将之前所有变量的操作都会刷新回主存,其他core的缓存失效,不管这些变量是否volatile,也就是只要操作在volatile写之前,另一个线程的volatile读发生在volatile写之后的话,这些操作读线程也能看到
       volatile关键字 :1,内存可见。2,禁止指令重排序。volatile关键字禁止指令重排序有两层意思:
  1)当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;
  2)在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。

对volatile写和volatile读的内存语义做个总结。

  • .线程A写一个volatile变量, 实质.上是线程A向接下来将要读这个volatile变量的某个线程发出了(其对共享变量所做修改的)消息。
  • .线程B读一个volatile变量,实质上是线程B接收了之前某个线程发出的(在写这个volatile变量之前对共享变量所做修改的)消息。
  • .线程A写一个volatile变量, 随后线程B读这个volatile变量, 这个过程实质.上是线程A通过主内存向线程B发送消息。

你可能感兴趣的:(#,java,JUC,java,多线程,volatile)