⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remoteclassv5.java

📁 solve readers-writers problem with RMI
💻 JAVA
字号:
/*################################################################################# remoteClassv5.java## Copyright (C) 2007 Fernando G. Tinetti## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA################################################################################ * *   This is "Version 5 server" i.e.:  *      1) Readers do not enter if there are writers waiting. *      2) After a writer, a waiting reader get access (just one) if there is one. *      3) The conditions under which readers or writers get access to the  *         resource are checked in a separate function. *      4) Other policies could be defined and checked in the proper function as  *         well. Also, it could be needed (for those policies) to define and use  *         specific local variables in order to enforce the policy (as variable  *         "last" in the current example). *      5) Each kind of process (i.e. readers or writers) now wait on a separate *         "watiting queue" associated to a specific monitor. An instance of the *         Object class is used directly as a monitor (which in fact it is).  *         More specifically, these monitors are used just as waiting and  *         synchronizing queues, just to make wait/notify calls on them. *      6) The remote methods are not "synchronized" now, since two monitors are *         used: one to test and set for access conditions and one to wait  *         (well, two in general, one for readers and one for writers). The  *         monitor to test and set for access is "this", the access server  *         itself. *   Used from startService, which creates and registers one object of  *   this class. */import java.rmi.RemoteException;               // For rmiimport java.rmi.server.UnicastRemoteObject;    // For rmiimport java.lang.Thread;                       // For reporting thread idspublic class remoteClassv5 extends UnicastRemoteObject implements remoteMethod{  private int calls;                // Just to count the number of rmi(nvocations)  private int readers, writers;     // Number of each kind of process currently accessing  private int rwait, wwait;         // Number of each kind of process currently waiting  private int last;                 // Last process on the resource 0 ==> Reader, guess 1    private Object rqueue, wqueue;    // Monitors used as queues    protected remoteClassv5() throws RemoteException   {    super();    calls   = 0;                // no service provided so far    readers = 0;                // no readers accessing    rwait   = 0;                // no readers waiting access    writers = 0;                // no writers accessing    wwait   = 0;                // no writers waiting access    last    = 0;                // assuming last access has been for readers    rqueue  = new Object();     // waiting queue for readers    wqueue  = new Object();     // waiting queue for writers  }  // -------------------           accessReader           -------------------  public Boolean accessReader() throws RemoteException  {    System.out.println("Entering accessReader, wwait = " + wwait + " calls = " + calls + " thread "  + Thread.currentThread().getId());    // Protect var. assignment from concurrent accesses    synchronized(this)    {      calls++;    }    // Controlling access for readers    while (readerHasToWait())    {      // This has to be moved to readerHasToWait in order to avoid race conditions      // rwait++;      synchronized(rqueue)      {        try        {          rqueue.wait();        }        catch(IllegalMonitorStateException e)        {          System.out.println("Exception IllegalMonitorStateException on accessReader on rqueue.wait()");          e.printStackTrace();          return Boolean.FALSE;        }        catch(InterruptedException e)        {          System.out.println("Exception InterruptedException on accessReader on rqueue.wait()");          e.printStackTrace();          return Boolean.FALSE;        }      }      // The number of waiting readers go back to 0 when every waiting reader is awakened      //rwait--;    }    // This reader gets the access    // This has to be moved to readerHasToWait in order to "record" that a reader    // has access so that writers can "see" it    // readers++;    // last = 0;    System.out.println("Leaving accessReader, calls = " + calls + " thread "  + Thread.currentThread().getId() + " readers: " + readers + " writers: " + writers);    return Boolean.TRUE;  }  // -------------------           readerHaveToWait           -------------------  protected synchronized Boolean readerHasToWait()  {    if (!((writers > 0) || ((wwait > 0) && (last == 0))))    {      // This reader obtains the access      readers++;      last = 0;      return Boolean.FALSE;    }    else    { // This reader has to wait      rwait++;      return Boolean.TRUE;    }  }  // -------------------           accessWriter           -------------------  public Boolean accessWriter() throws RemoteException  {    System.out.println("Entering accessWriter, calls = " + calls + " thread "  + Thread.currentThread().getId());    // Protect var. assignment from concurrent accesses    synchronized(this)    {      calls++;    }    // Controlling access for writers    while (writerHasToWait())    {      // This has to be moved to readerHasToWait in order to avoid race conditions      // wwait++;      synchronized(wqueue)      {        try        {          wqueue.wait();        }        catch(IllegalMonitorStateException e)        {          System.out.println("Exception IllegalMonitorStateException on accessWriter on wait()");          e.printStackTrace();          return Boolean.FALSE;        }        catch(InterruptedException e)        {          System.out.println("Exception InterruptedException on accessReader on wait()");          e.printStackTrace();          return Boolean.FALSE;        }      }      // The number of waiting writers go back to 0 when every waiting reader is awakened      //wwait--;    }        // This writer gets the access     // This has to be moved to writerHasToWait in order to "record" that a writer    // has access so that readers can "see" it    //writers++;    //last = 1;    System.out.println("Leaving accessWriter, calls = " + calls + " thread "  + Thread.currentThread().getId() + " readers: " + readers  + " writers: " + writers);    return Boolean.TRUE;  }  // -------------------           readerHaveToWait           -------------------  protected synchronized Boolean writerHasToWait()  {    if (!((writers > 0) || (readers > 0) || ((rwait > 0) && (last == 1))))    {      // This writer obtains the access      writers++;      last = 1;      return Boolean.FALSE;    }    else    { // This writer has to wait      wwait++;      return Boolean.TRUE;    }  }  // -------------------           leaveReader           -------------------  public Boolean leaveReader() throws RemoteException  {    System.out.println("Entering leaveReader, reader = " + readers + ", wwait = " + wwait);    // This reader doesn't access anymore, blocking other processes that update the same var.    // and, also, prevent "other" writers to get immediate access in case of waiting writers    synchronized (this)    {      readers--;      // Now, only waiting writers should be awakened if no more readers accessing      if (readers == 0)      {        synchronized (wqueue)        {          try          { // wakeup every waiting writer            wqueue.notifyAll();          }          catch(IllegalMonitorStateException e)          {            System.out.println("Exception IllegalMonitorStateException on leaveReader on notifyAll()");            e.printStackTrace();            return Boolean.FALSE;          }        }        // No waiting writers on the wqueue (all of them have been awakened)         wwait = 0;      }    }    System.out.println("Leaving leaveReader" + " readers: " + readers + " writers: " + writers);    return Boolean.TRUE;  }  // -------------------           leaveWriter           -------------------  public Boolean leaveWriter() throws RemoteException  {    System.out.println("Entering leaveWriter");    // Blocking other processes that update/check values of shared variable/s    synchronized (this)    {      // This writer doesn't access anymore      writers--;      // Do not give preference to any kind of process      // Thus, every waiting process (readers and writers) should be awakened      synchronized (wqueue)      {        try        { // wakeup every waiting writer          wqueue.notifyAll();        }        catch(IllegalMonitorStateException e)        {          System.out.println("Exception IllegalMonitorStateException on leaveWriter on wqueue.notifyAll()");          e.printStackTrace();          return Boolean.FALSE;        }      }      synchronized (rqueue)      {        try        { // wakeup every reader waiting          rqueue.notifyAll();        }        catch(IllegalMonitorStateException e)        {          System.out.println("Exception IllegalMonitorStateException on leaveReader on rqueue.notifyAll()");          e.printStackTrace();          return Boolean.FALSE;        }      }      // Every process is now trying to get access, not waiting      rwait = 0;      wwait = 0;    }    System.out.println("Leaving leaveWriter" + " readers: " + readers + " writers: " + writers);    return Boolean.TRUE;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -