Mesa & Hoare Monitor

来源:互联网 发布:传热计算软件 编辑:程序博客网 时间:2024/05/16 05:56

Monitor 相当于一个封闭的盒子,Monitor对里面的东西进行监控。

Java的Monitor,类似于Mesa。以前只知道Java里面同不用synchronized,但是其实每一个Object可以被当作Monitor,控制里面所有synchronized 方法,variable。

当有一个process 进入synchronized 函数后,其它的process,都会被block在外。直到,这个process运行完,或者wait,主动退出。buffer 是解释Monitor最好的例子,当一个process,get或者put时,条件不符合,然后主动wait (process 进入一个monitor waiting queue),直到有一个process调用了notify,这时有一个在 waiting queue 里面的waiting process,会醒来。进入while loop再检查一遍条件是否符合,如果符合就继续。

之所以要进入while loop再检查一遍是因为有可能调用的是notifyAll,许多process一起醒来,最先醒来的已经改变了Condition Variable(条件),当另一个process 检查的时候条件已经不符合了。

Mesa Monitor,一个process notify 以后继续执行,其它所有的waiting process都醒来,检查条件,但是只有一个会真正的执行。为了避免starvation(有的waiting process)永远抢不到,时间等的最久的可能会最先执行(增加了scheduling的概念)。Mesa Monitor 优点是,反应速度快,notifying process 不用等,继续执行

Hoare Monitor,的特点是一个process notify以后,条件肯定满足,所以不需要while loop,醒来的process直接执行下一步。

另外Mesa Monitor 有一个invariant,当有process 在monitor里面是为false,其他时候都是true。在wait前和wait return 以后invariant can be assumed,必须是hold,其它时候不能确定。也就是说当要修改monitor状态的时候invariant 必须hold,比如修改waiting queue

class Buffer {            private char [] buffer;            private int count = 0, in = 0, out = 0;            Buffer(int size)            {                 buffer = new char[size];            }             public synchronized void Put(char c) {                 while(count == buffer.length)                  {                      try { wait(); }                      catch (InterruptedException e) { }                       finally { }                  }                  System.out.println("Producing " + c + " ...");                 buffer[in] = c;                  in = (in + 1) % buffer.length;                  count++;                  notify();             }                public synchronized char Get() {                 while (count == 0)                  {                      try { wait(); }                      catch (InterruptedException e) { }                       finally { }                  }                  char c = buffer[out];                  out = (out + 1) % buffer.length;                 count--;                 System.out.println("Consuming " + c + " ...");                  notify();                  return c;            }      }

原创粉丝点击