美文网首页
一次搞懂Java互斥的"等待-通知"机制

一次搞懂Java互斥的"等待-通知"机制

作者: yes的练级攻略 | 来源:发表于2019-03-17 12:39 被阅读0次

    话不多说咱们先看一段代码哈哈哈

       public class A {   
          private int checkedIdCard = 0;
            void handle(int idCard){
               synchroinzed (A.class){
                 while(idCard==0){
                   //等你给他身份证
                 };        
                  //办理
                 }
            }
            void pay(int moeny){
               synchroinzed (A.class){
                  //付钱
                 }
            }
       }
        
       public class You {   
            private A a;    //单例工作人员A当然只会有一个
            private int idCard = 0;   //0 表示你没带身份证
            boolean applyForPasspost(int idCard){
               a.handle(idCard);
               a.pay(170);  //在杭州办理护照是160块,再加10块邮费
            }
           //省略带身份证的赋值方法
       }
    

    这段代码的意思就是我们去行政服务中心办护照,工作人员A来服务我们,我们需要给他我们的身份证才能办理对吧,办好之后付了钱才会生效。
    因为A同一时刻只能服务一个人,所以我们给A加了个锁。但是上面代码有一点不符合我们的现实逻辑,

                 while(idCard==0){
                   //等你给他身份证
                 };  
    

    就是这一段代码,就是说如果你排队叫号,叫到你了你去柜台,发现你没带身份证,那正常情况下就是你得会回家拿身份证,工作人员A是不会让你占着位置等你的,而是会叫下一号。如果不叫下一号等你回家拿身份证来效率多低啊?那放在我们代码里面也是一样的!
    所以如何提高效率呢?这就引入了"等待-通知"机制了!
    我们改造下上面的类A

       public class A {   
            void handle(int idCard){
               synchroinzed (A.class){
                 while(idCard==0){
                   //等你给他身份证
                     try{
                          wait();
                        }catch(Exception e){
                        }     
                   };        
                  //办理
                 }
            }
            void pay(int moeny){
               synchroinzed (A.class){
                  //付钱
                   notifyAll();
                 }
            }
       }
    

    经过这个改造就符合我们的正常情况了!但你去了柜台发现你没身份证,工作人员告诉你不好意思你回去拿吧(wait)!就是让你去一边等着去,下一位!
    翻译到java中就是,你这个线程来执行办理护照,但是你不满足条件所以你就一边等着(解锁了),不要阻塞着大家!这样效率就提高了很多了!然后等一个人办理好之后就是通知一下那些等待的线程,看看你们现在带身份证了没?如果带来再来排队!
    咱们再深入的剖析一下这个流程



    就是我们被锁的方法就会被统一包起来!所有的进出都被synchroinzed 把控了。
    等待对列就是存放那些等待的想进入这个临界区的线程们,条件变量就是对应着我们上面代码的IdCard,调用了wait()就表示不满足我们的条件,所以让当前线程进去条件变量等待对列!
    再调用notifyAll()表面现在条件满足了!然后那些条件对待对列中的所有线程出去到等待对列中排队了!
    这个说说为什么用notifyAll()而不是notify(),因为notify()是随机唤醒一个条件变量等待对列中的线程去让他们出去继续排队!那就是有可能一些线程永远不会被通知到!那不玩完了么?所以推荐使用notifyAll();
    还有一点我们用了

                 while(idCard==0){
                         wait();  //省略try catch
                 };  
    

    为什么加了个while循环再一次对条件进行判断呢?
    因为notifyAll()的时候你的条件是满足的!但是你又出去排队了,那指不定排队轮到你的之后条件又不满足了!所以需要加个while循环!
    还有如果你用的是Lock其实也是一样的意思!
    所以引入了"等待-通知"机制提高了我们代码执行的效率!希望以上内容让大家有所收获!


    相关文章

      网友评论

          本文标题:一次搞懂Java互斥的"等待-通知"机制

          本文链接:https://www.haomeiwen.com/subject/kfnymqtx.html