作家
登录

Java面试官最爱问的volatile关键字

作者: 来源: 2018-01-19 11:44:46 阅读 我要评论

  •    } 
  • 这段代码不仅仅受到重排序的困扰,即使1、2没有重排序。3也不会那么顺利的履行的。假设照样线程1先履行write操作,线程2再履行multiply操作,因为线程1是在工作内存里把flag赋值为1,不必定急速写回主存,所以线程2履行时,multiply再大年夜主存读flag值,仍然可能为false,那么括号里的语句将不会履行。 如不雅改成下面如许:

    1. int a = 0; 
    2. volatile bool flag = false
    3.  
    4. public void write() { 
    5.    a = 2;              //1 
    6.    flag = true;        //2 
    7.  
    8. public void multiply() { 
    9.    if (flag) {         //3 
    10.        int ret = a * a;//4 
    11.    } 

    那么线程1先履行write,线程2再履行multiply。根据happens-before原则,这个过程会知足以下3类规矩: 法度榜样次序规矩:1 happens-before 2; 3 happens-before 4; (volatile限制了指令重排序,所以1 在2 之前履行) volatile规矩:2 happens-before 3 传递性规矩:1 happens-before 4 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存 当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,线程接下来将大年夜主内存中攫取共享变量。

    起首我答复是不克不及包管原子性,如果说能包管,也执偾对单个volatile变量的读/写具有原子性,然则对于类似volatile++如许的复合操作就力所不及了,比如下面的例子:

    1. public class Test { 
    2.     public volatile int inc = 0; 
    3.   
    4.     public void increase() { 
    5.         inc++; 
    6.     } 
    7.   
    8.     public static void main(String[] args) { 
    9.         final Test test = new Test(); 
    10.         for(int i=0;i<10;i++){ 
    11.             new Thread(){ 
    12.                 public void run() { 
    13.                     for(int j=0;j<1000;j++) 
    14.                         test.increase(); 
    15.                 }; 
    16.             }.start(); 
    17.         } 
    18.   
    19.         while(Thread.activeCount()>1)  //包管前面的线程都履行完 
    20.             Thread.yield(); 

        推荐阅读

        剖析内存中的程序之秘,快来看吧!

      年前最后一场技巧盛宴 | 1月27日与京东、日记易技巧大年夜咖畅聊智能化运维成长趋势! ELF Binary Image Mapped Into MemoryKernel/User Memory Split内存治理是操作体系的核心义务;它对法>>>详细阅读


      本文标题:Java面试官最爱问的volatile关键字

      地址:http://www.17bianji.com/lsqh/40382.html

    关键词: 探索发现

    乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

    网友点评
    自媒体专栏

    评论

    热度

    精彩导读
    栏目ID=71的表不存在(操作类型=0)