RMI und Threads

Stand: März 2008

irgendein Text

Syntax:

Seitenanfang

Basisschnittstelle ICounter


import java.rmi.Remote;
import java.rmi.RemoteException;

   public interface ICounter extends Remote {
      void counter(int x) throws RemoteException;
      int getCounter() throws RemoteException;
      int inkrement() throws RemoteException;
      int dekrement() throws RemoteException;
   }

Kategorie: Java

Seitenanfang

Server Objekt - Klasse Server


import java.net.InetAddress;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RemoteServer;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.Unreferenced;
import java.net.UnknownHostException;

   public class Server implements ICounter, Unreferenced {
   
      private static Server       serv;
      private static Registry     registry;
      private static IObjThread   servDekrement;
      private static IObjThread   servInkrement;
      private static int          count;

      Server() { super(); }
      
      public void counter(int x) {
         count += x;
      }
      public int inkrement() {
         return count++;
      }
      public int dekrement() {
         return count--;
      }
      public int getCounter() {
         return count;
      }
      public void unreferenced() {
         java.util.Date date = new java.util.Date();
         System.out.println("\nKeine weiteren Referenzen vorhanden " + date + "\n");
      }
      /*protected void finalize() throws Throwable {
         super.finalize();
         java.util.Date date=new java.util.Date();
         System.out.println("Aufräumen ja oder nein, das ist hier die Frage...? " + date);
      }*/

      public static void main(String[] args) throws UnknownHostException {
         
         serv = new Server();

         String mldg = "usage: java Server <run|stop> <logging:true>";
         String help = "\n usage rmiregistry:\n" +
                        "-J-Djava.class.path=\n" +
                        "-J-Djava.rmi.server.hostname=\n\n" +
                        "Host Name/Adresse: " + InetAddress.getLocalHost().toString() + "\n\n" +
                        mldg;
         
         if( args.length == 1 ) {}
         else if ( args.length == 2 ) {
            boolean log = Boolean.valueOf(args[1].toLowerCase());			
            if (log) 
               RemoteServer.setLog( System.out ); // Aufrufe loggen
         }
         else {
            System.out.println(help);
            return;
         }
         
         for ( String s : args) {
            if ( s.equals("run") ) {
               System.out.println("\nAm Server anmelden.\n");
               
               /*try {
               /* über den Server RMI-Registry starten, 
                * Namensdienst auf Standardport 1099 anmelden *//* 
                  LocateRegistry.createRegistry( Registry.REGISTRY_PORT );
                  System.out.printf("Am Server anmelden.");
               }
               catch (RemoteException e) {
                  System.exit(0); // .exit als Holzhammer, wenn bereits gestartet.
               }*/
               
               // Remote Obj erzeugen, exportieren und in der Reg anmelden
               try {
                  ICounter servCounter = (ICounter) UnicastRemoteObject.exportObject( serv, 0 );
                  Inkrement inkrement = new Inkrement();
                  servInkrement = (IObjThread) UnicastRemoteObject.exportObject( inkrement, 0 );
                  Dekrement dekrement = new Dekrement();
                  servDekrement = (IObjThread) UnicastRemoteObject.exportObject( dekrement, 0 );
                  /* Das Remote Obj dem Namensdienst bekannt machen,
                   * localhost:1099, Name Obj, Remote Obj 
                   * hier mit der Methode .rebind()
                   * Den Dienst einen neuen Eintrag hinzufügen bzw. 
                   * einen vorhandenen überschreiben.
                   * (ist hier nicht möglich s. o. Holzhammer)
                   * Methode .bind() würde bei einem vorhandenen Dienst
                   * AlreadyBoundException auslösen.*/
                  registry = LocateRegistry.getRegistry();
                  registry.rebind( "ICounter", servCounter );
                  registry.rebind( "IInkrement", servInkrement );
                  registry.rebind( "IDekrement", servDekrement );
                  /* Ausführen und im DosPrompt des "Servers" rumideln lassen
                   * Konstruktor -> new Thread(this).start(); 
                   * ### entfällt da ein Konstruktor nicht vererbt werden kann.
                   * ### @see ObjThread#start() */
                  servInkrement.start(); // inkrement.start();
                  servDekrement.start(); // dekrement.start();
               }
               catch (RemoteException e) {
                  System.out.println(e.getMessage());
               }
               catch (NotBoundException e) {
                  System.out.println(e.getMessage());
               }               
            }
            else if ( s.equals("stop") || s.equals("td") ) {
               mldg = "Jedes Ende hat auch einen Anfang... usage: <run>";
               // Die Remote Obj aus der Reg entfernen
               try {
                  registry = LocateRegistry.getRegistry();
                  servInkrement = (IObjThread) registry.lookup( "IInkrement" );
                  servDekrement = (IObjThread) registry.lookup( "IDekrement" );
                  // die Schleife vorab beenden
                  if ( s.equals("stop") ) {
                     System.out.println("\nAm Server abmelden.\n");
                     servInkrement.setInterrupt();
                     servDekrement.setInterrupt();
                  }
                  // Hintertür
                  if ( s.equals("td") ) {
                     System.out.println("\n mit dem Holzhammer den Server abmelden.\n");
                     servInkrement.setStop();
                     servDekrement.setStop();
                  }
                  registry.unbind( "IInkrement" );
                  registry.unbind( "IDekrement" );
                  registry.unbind( "ICounter" );
               }
               catch (RemoteException e) {
                  System.out.println(e.getMessage() + "\n" + mldg);
               }
               catch (NotBoundException e) {
                  System.out.println(e.getMessage() + "\n" + mldg);
               }
               catch (InterruptedException e) {
                  System.out.println(e.getMessage());
               }
            }
            else if ( s.equals("?") ) {
               System.out.println(help);
               return;
            }
         }
      }
   }

Kategorie: Java

Seitenanfang

Basisschnittstelle IObjThread


import java.rmi.Remote;
import java.rmi.RemoteException;

   public interface IObjThread extends Remote {
      // Server
      void start() throws InterruptedException, RemoteException;
      void setInterrupt() throws InterruptedException, RemoteException;
      void setStop() throws InterruptedException, RemoteException;
      // Client
      void isWait(boolean b) throws InterruptedException, RemoteException; 
      void doNotify() throws InterruptedException, RemoteException;
   }

Kategorie: Java

Seitenanfang

Server Objekt - Klasse ObjThread


import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Timer;
import java.util.TimerTask;

   public class ObjThread implements Runnable, IObjThread {
   
      public  static   Registry   registry;
      public           ICounter   ic;
      private          boolean    wait;
      private static   boolean    still;
      private          Timer      timer;
      private          TimerTask  task;
      private          Object     lock = new Object();
      public           long       delay;
   
      ObjThread() { delay = 0; }

      // Server
      public void start() {
         try {
            registry = LocateRegistry.getRegistry();
         }
         catch (RemoteException e) {}
         new Thread(this).start();
      }
      public void setInterrupt() {
         Thread.currentThread().interrupt();
         System.out.println("\nDurch Interrupt beendet\n");
      }
      public void setStop() throws ThreadDeath {
         try {
            Thread.currentThread().stop(); }
         catch (ThreadDeath td) {
            System.out.println( "\nDie Initialien sind`s [T]hread[D]eath ;)\n" );
            //throw td; 
         }
      }
      // Client
      public void doWait() {
         if (wait) {
            synchronized (lock) {
               try {
                  System.out.println("\nIch warte bis ein Stueckchen " + 
                                       "Weltraumschrott direkt vor meine Fuesse faellt\n");
                  stillWaiting(true);
                  lock.wait();
               }
               catch (InterruptedException e) {
                  e.printStackTrace();
               }
            }
         }
      }
      public void isWait(boolean b) {
         wait = b;
      }
      public void stillWaiting(boolean b) {
         still = b;
         timer = new Timer();
         task = new TimerTask() {
            public void run() {
               if (still) {
                  System.out.println("\nIch warte immer noch...\n");
                  stillWaiting(true);
               }
            }
         };
         timer.schedule(task, delay);
      }
      public void doNotify() {
         timer = new Timer();
         task = new TimerTask() {
            public void run() {
               synchronized (lock) {
                  lock.notify();
                  stillWaiting(false);
                  System.out.println("\nAlarms notify the Thread.\n");
               }
            }
         };
         timer.schedule(task, delay); 
      }
      @Override public void run() {}
   }

Kategorie: Java

Seitenanfang

Inkrement(Thread-1) von ObjThread abgeleitet


import java.rmi.NotBoundException;
import java.rmi.RemoteException;

   public class Inkrement extends ObjThread {

      Inkrement() { 
         super();
         super.delay = 2000L;
      }
      @Override public void run() {
         while ( ! Thread.currentThread().isInterrupted() ) {
            try {
               Thread.sleep(delay);
               ic = (ICounter) registry.lookup( "ICounter" );
               ic.inkrement();
               System.out.printf("\nThread %s - ICounter.inkrement -> %d\n\n", 
                           Thread.currentThread().getName(), ic.getCounter());
               doWait();
            }
            catch (InterruptedException e) {}
            catch (RemoteException e) {}
            catch (NotBoundException e) {}
         }
      }
   }

Kategorie: Java

Seitenanfang

Dekrement(Thread-2) von ObjThread abgeleitet


import java.rmi.NotBoundException;
import java.rmi.RemoteException;

   public class Dekrement extends ObjThread {

      Dekrement() { 
         super();
         super.delay = 4000L;
      }
      @Override public void run() {
         while ( ! Thread.currentThread().isInterrupted() ) {
            try {
               Thread.sleep(delay);
               ic = (ICounter) registry.lookup( "ICounter" );
               ic.dekrement();
               System.out.printf("\nThread %s - ICounter.dekrement -> %d\n\n",
                           Thread.currentThread().getName(), ic.getCounter());
               doWait();
            }
            catch (InterruptedException e) {}
            catch (RemoteException e) {}
            catch (NotBoundException e) {}
         }
      }
   }

Kategorie: Java

Seitenanfang

Klasse Client


import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
 
   public class Client { 

      static ICounter    ic;
      static IObjThread  ii;
      static IObjThread  id;

      public static void main( String[] args ) 
      throws InterruptedException, RemoteException, NotBoundException, MalformedURLException { 
    
         String help = "\nusage: java Client <hostname or ipaddress> <option> <value>\n" +
                        "\n<option:get>\n" +
                        "\n<option:add> <value:any Integer>\n" +
                        "\n<option:run|wait> <value:inkrement|dekrement>\n";

         System.out.println("Server kontaktieren\n");

         if (args.length == 2) {}
         else if ( args.length == 3 ) {}
         else {
            System.out.println(help);
            return;
         }

         ic = (ICounter) Naming.lookup("rmi://" + args[0] + "/ICounter");
         ii = (IObjThread) Naming.lookup("rmi://" + args[0] + "/IInkrement");
         id = (IObjThread) Naming.lookup("rmi://" + args[0] + "/IDekrement");

         if ( args[1].equals("get") ) 
            System.out.println("getCounter: " + ic.getCounter());

         if ( args[1].equals("add") ) {
            try {
               int i = Integer.parseInt(args[2]);
               ic.counter(i);
               System.out.printf("add: %d -> getCounter: %d\n", i, ic.getCounter());
               }
               catch (NumberFormatException e) {
                  System.out.printf("<value> %s ist kein Integer!", args[2]); }
               catch (ArrayIndexOutOfBoundsException e) {
                  System.out.println("<add> <any Integer>."); }
         }
         if ( args[1].equals("?") ) {
            System.out.println(help);
            return;
         }
         if ( args[1].equals("run") ) {
            if (args[2].toLowerCase().equals("dekrement")) {
               id.isWait(false);
               id.doNotify();
            }
         }
         if ( args[1].equals("wait") ) {
            if (args[2].toLowerCase().equals("dekrement")) {
               id.isWait(true);
            }
         }
         if ( args[1].equals("run") ) {
            if (args[2].toLowerCase().equals("inkrement")) {
               ii.isWait(false);
               ii.doNotify();
            }
         }
         if ( args[1].equals("wait") ) {
            if (args[2].toLowerCase().equals("inkrement")) {
               ii.isWait(true);
            }
         }
      }
   }

Kategorie: Java

Seitenanfang