Blatt 11.1
Aufgabe 12: Aufwärmen mit JavaParty
Vorbereitung
Verwenden Sie Java bzw. Javaparty für die Lösung der Aufgabe auf
diesem Aufgabenblatt.
Stellen Sie sicher, daß sich in Ihrem
Shell-Initialisierungsskript Kommandos der folgenden Art befinden:
source /ToolMan/Modules/init/tcsh
module add jdk/1.4.2_13
module add jp/1.9.4
Wenn Sie die bash als Login-Shell verwenden, müssen Sie in der
ersten Zeile "tcsh" durch "bash" ersetzen.
Sie können auch andere Versionen eines JDK verwenden, vermeiden Sie
aber derzeit besser die Auswahl eines JDK der Version 5 bzw. 1.5.
Aufgabe 12.1
Schreiben Sie ein kleines JavaParty-Programm, das einen verteilten
"Drucker" simuliert. Schreiben dafür eine entfernte
Klasse Printer, die den Drucker darstellt, und eine
lokale Klasse DistributedPrinter, die das
Hauptprogramm enthält.
Die Klasse Printer soll in ihrer print()-Methode
eine als Argument übergebene Nachricht ausdrucken und zusätzlich die
Knotennummer ausgeben, auf der sich der Drucker befindet.
remote class Printer {
public void print(String what) {
int id = jp.lang.DistributedRuntime.getMachineID();
System.out.println(what + " (at node " + id + ")");
}
}
Die Klasse cp.printer.v1.DistributedPrinter soll in ihrer
main()-Methode N Instanzen von Printer
anlegen und auf allen die Methode print() mit der Nachricht
"Listing on printer i" aufrufen, wobei i durch die
Nummer des Druckers (also 0..N-1) ersetzt werden
soll. Die Anzahl der Instanzen N wird als
Kommandozeilenargument übergeben.
package cp.printer.v1;
// ...
public class DistributedPrinter {
public static void main(String[] args) {
// ... hier ergänzen ... !
}
}
Hinweis: Mit der Servicemethode
jp.lang.DistributedRuntime.getMachineID() können Sie die
Nummer der lokalen virtuellen Maschine ermitteln.
Um Ihr Programm zu testen, übersetzen Sie es mit dem Befehl
javaparty compile -d ~/classes DistributedPrinter.java
(oder ähnlich, wenn Sie z.B. ein anderes Verzeichnis für die
übersetzten Klassen benutzen) und starten Sie es (z.B. auf
carla1) mit dem Kommando
jpinvite -cp ~/classes -nodenames carla1,carla2 cp.printer.v1.DistributedPrinter
Hilfe zu allen JavaParty-Kommandos gibt es hier.
Statt die Kommandozeilenoption -nodenames zu verwenden
können Sie auch eine Datei ~/.jp-nodefile anlegen, in der
die verwendeten Knoten aufgelistet sind, jeweils einer pro
Zeile.
Geben Sie Ihre Version von DistributedPrinter.java (die
die beiden Klassen Printer und DistributedPrinter
enthält) über den Praktomaten ab.
Aufgabe 12.2
Nun soll eine der Printer-Instanzen umziehen, das heisst,
von einer virtuellen Maschine auf eine andere verlegt werden.
Legen Sie eine Kopie von DistributedPrinter im Paket
cp.printer.v2 an. Ändern Sie das Programm so ab, dass die
print()-Methode von der letzten der erzeugten
Printer-Instanzen (die mit der Nummer N-1) zweimal
aufgerufen wird, aber lassen Sie die Instanz dazwischen die
virtuelle Maschine wechseln.
Sie brauchen drei weitere Service-Methoden aus
jp.lang.DistributedRuntime:
- Mit der Methode getLocation(RemoteObject)
können Sie herausfinden, auf welcher virtuellen Maschine ein
bestimmtes Objekt plaziert wurde,
- die Methode getMachineCnt() sagt Ihnen, wieviele
virtuelle Maschinen gestartet wurden,
- und migrate(RemoteObject, new_id) verlegt die Heimat
des entfernten Objekts auf die virtuelle Maschine mit der ID
new_id.
Hinweis: Achten Sie darauf, dass Sie als Ziel für migrate()
eine gültige ID verwenden. Die ID's liegen im Bereich
0..getMachineCnt()-1.
Geben Sie auch diese Version von DistributedPrinter über
den Praktomaten ab.
Aufgabe 12.3
Nun soll der globale Tintenverbrauch aller Drucker
protokolliert werden. Fügen Sie dazu zunächst in DistributedPrinter
eine statische Integer-Variable inkUsage ein, die
Sie mit 0 initialisieren, ferner eine statische Methode
consumeInk(), die ink um 1
inkrementiert.
Ändern Sie die Methode Printer.print() so ab, dass nun
nach der jeweiligen Ausgabe noch consumeInk() aufgerufen
wird. Außerdem soll die Ausgabe den bisherigen Tintenverbrauch
(nach der Ausgabe) enthalten:
System.out.println(what + " (at node " + id + ", ink usage " + inkUsage + ")");
Sorgen Sie mit Hilfe der Service-Methode migrate()
(vergl. Aufgabe 12.2) oder der @at Annotation dafür,
dass alle Printer-Instanzen auf unterschiedlichen
virtuellen Maschinen plaziert werden. Das ist natürlich nur möglich,
wenn die Anzahl der per Kommandozeilenparameter geforderten
Printer-Instanzen kleiner oder gleich der Anzahl der gestarteten VMs
ist. Andernfalls verteilen Sie die Instanzen reihum. Das
Umziehen der letzten Instanz aus Aufgabe 12.2 soll hier nicht
durchgeführt werden.
Testen Sie Ihr Programm! Ändern Sie das Programm so ab, dass es so
funktioniert wie beabsichtigt und geben Sie es als
cp.printer.v3.DistributedPrinter.java ab.
|