# Verständnisfrage zu RMI und Threads



## macci (8. Jun 2011)

Hallo,

ich hoffe, ich habe das richtige Forum gewählt ...

Hallo,

ich muss eine Hausaufgabe lösen und komme mit RMI, Server, Client und Threads irgendwie nicht zurecht.

Von der Idee:
Es geht um eine Reservierungsverwaltung mit einer MySQL-Datenbank im Hintergrund.
Es gibt eine GUI, wo man Hotels anlegen/löschen, Personen anlegen/löschen und Reservierungen anlegen kann.

Ich habe versucht, ein kleines Beispiel zusammenstellen (ungetestet und unkompiliert - kann also durchaus sein, dass kleine Fehler darin sind.)

Und nun kommen Threads ins Spiel ... ich habe immer nur sehr einfache Beispiele gefunden, ohne Client und Server oder mit nur einer oder zwei Methoden.
Das hier scheint mir grundsätzlich sehr einleuchtend
Threading in RMI

Aber wenn ich nun Threads verwenden will, damit der User z.B. die Fenstergrösse ändern kann, während eine Methode ausgeführt wird. Oder, dass das Anzeigen der Personen auch funktioniert, wenn das Einfügen noch nicht abgeschlossen ist.
Braucht dann nur der Client einen/mehrere Threads und enthält der Thread dann? Muss ich einen für jede Methode machen? ???:L

Server sieht so ähnlich aus ..
(Klasse PersonDB regelt die Datenbankzugriffe)


```
public interface Server extends Remote {
  public void addPerson(String fn, String ln) throws RemoteException;
  public void deletePerson(String fn, String ln) throws RemoteException;
  public Collection<String> getAllPersons() throws RemoteException;
  ...
}
```



```
public class ServerImpl extends UnicastRemoteObject implements Server {
  public ServerImpl() throws RemoteException {
    super();
  }
  
  public void addPerson(String fn, String ln) throws RemoteException {
    PersonDB.insert(String fn, String ln);
  }
  
  public void deletePerson(String fn, String ln) throws RemoteException {
    PersonDB.delete(String fn, String ln);
  }
  
  public Collection<String> getAllPersons() throws RemoteException {
    return PersonDB.getAllPersons();
  }
  
  ...
  
  public static void main (String args[]) {
    try {
      LocateRegistry.createRegistry(1099);
      Server s = new ServerImpl();
      java.rmi.Naming.rebind("rmi://" + host_port + "/Server", s);
      System.out.println("Server running ...");
    } catch (Exception e) System.out.println(e);
  }
}
```

Client mit GUI greift auf die Servermethoden zu und sieht sehr vereinfacht und in Auszügen so aus


```
public class Client extends Frame implements ActionListener, ItemListener {
  Panel pPanel;
  List pList;
  Button pAddButton, pListButton;
  TextField pFirstName, pLastName;
  
  private Server s;
  
  public Client() {
    super("Testprogramm");
    setSize(600, 400);
    setLayout(newBorderLayout(5,10));
    
    try {
      this.s = (Server)java.rmi.Naming.lookup("rmi://" + host_port + "/Server");
    } catch (Exception e) {
      System.err.println(e);
    }
    
    pPanel = buildPanel();
    this.add(pPanel);
 
  }

  private Panel buildPanel() {
    pPanel = new Panel(new GridLayout(2,3));
    pList = new java.awt.List();
    pList.addActionListener(this);
    pFirstName = new TextField();
    pFirstName.addActionListener(this);
    pLastName = new TextField();
    pLastName.addActionListener(this);
    pAddButton = new Button("Hinzufügen");
    pAddButton.addActionListener(this);
    pListButton = new Button("Anzeigen");
    pListButton.addActionListener(this);
    pPanel.add(pFirstName);
    pPanel.add(pLastName);
    pPanel.add(pList);
    pPanel.add(pAddButton);
    pPanel.add(pListButton);
    return pPanel;
  }

  private void listPersons() {
    try {
      Collection<String> c = new ArrayList<String>();
      c = s.getAllPersons();
      if (c != null) {
        pList.removeAll();
        for (String s : c)
          pList.add(s);
      } else
          pList.add("Keine Personen vorhanden.");
    } catch (RemoteException e) System.err.println(e);
  }
  
  public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    if (source == pAddButton) {
      String fn = pFirstName.getText();
      String ln = pLastName.getText();
      try {
        s.addPerson(fn, ln);
      } catch (RemoteException re) System.err.println(re);
    } else if (source == pListButton) {
      listPersons();
    }
  }
  
  public static void main (String[] args) {
    Client c = new Client("localhost");
    s.setVisible(true);
  } 
}
```


----------



## SlaterB (9. Jun 2011)

soviel Text für so kleine Frage?
ist doch nichts dabei, mit RMI scheint es auch nicht unbedingt zu tun zu haben

jede Aktion eines ActionListeners und Co. kann eine gewisse Zeit dauern, also muss jede dieser Aktionen in einen Thread gelegt werden,
ob dabei jeweils ein neuer Thread gestartet wird oder die Aufgabe verpackt und an einen allgemeinen ExecutorService (hat nix mit RMI zu tun, nicht verwechseln) übergeben wird, ist da doch nur ein Detail,
wird höchstens interessant wenn es nur einen Thread zur Ausführung gibt aber mehrere Aufgaben gleichzeitig angeklickt werden, dann kommen die vielleicht in eine Wartschlange..

nützlich kann z.B. eine Basisklasse RunnerActionListener sein, die die actionPerformed-Methode aufruft, darin einen Thread startet der eine andere Methode action2() aufruft und bei Verwendung von RunnerActionListener einfach immer die neue Methode implementieren statt früher die alte,
diese am besten final machen, dann kann sie nicht versehentlich überschrieben werden,
so wären ohne direkten Codeaufwand alle ActionListener direkt nebenläufig


----------



## macci (16. Jun 2011)

> soviel Text für so kleine Frage?



Der Fluch der Unwissenden ... 
Sorry, aber ich steh' da echt total daneben.

Ich werde mir deinen Vorschlag mal in Ruhe überlegen - vielen Dank.


----------

