Wir machen einige Prototyping-Arbeiten und wir fragen uns, ob es möglich ist, einen Thread zu unterbrechen, der einen RMI-Aufruf durchgeführt hat. Wenn wir interrupt () in diesem Thread aufrufen, würde es eine InterruptedException auslösen? (oder sollte es?) Unsere Tests zeigen derzeit, dass dies nicht der Fall ist. Ich frage mich nur, wie es sein sollte.
Die Unterbrechbare RMI-Bibliothek bietet einen Mechanismus zum Unterbrechen von RMI-Aufrufen. Wenn ein Thread eine RMI-Methode aufruft, blockiert der Thread normalerweise, bis die RMI-Methode zurückkehrt. Wenn der Methodenaufruf zu lange dauert (z. B. wenn der RMI-Server ausgelastet ist oder hängt oder wenn der Benutzer die RMI-Operation abbrechen möchte), gibt es keine einfache Möglichkeit, den blockierenden RMI-Aufruf zu unterbrechen und die Steuerung an den RMI-Thread zurückzugeben . Die Interruptible RMI-Bibliothek bietet diese Funktionalität.
Die Bibliothek besteht aus zwei Hauptkomponenten: einer RMISocketFactory und einer ThreadFactory. RMI-Aufrufe, die in einem Thread von der bereitgestellten ThreadFactory an eine RMI-Schnittstelle unter Verwendung von Sockets aus der RMISocketFactory vorgenommen werden, können durch Aufrufen von Thread # interrupt () für den Clientthread unterbrochen werden. Also, es ist wirklich einfach zu bedienen. Beachten Sie jedoch auch auf der Serverseite, dass Sie möglicherweise einen Aufruf an eine praktische Hilfsmethode hinzufügen möchten, um sicherzustellen, dass der aktuelle Thread kein "Zombie" oder verwaister Thread ist, der bereits vom Client "unterbrochen" wurde.
Einen RMI-Server programmgesteuert anhalten:
RMI-Server starten einen Thread, der niemals endet. Dies ist so, dass der Server persistent ist, bis er manuell heruntergefahren wird. Sie können jedoch eine Remote-Methode, shutDown()
, für den Remoteserver bereitstellen. Diese Methode startet einen Thread zum Herunterfahren. Der Thread zum Herunterfahren wartet auf eine notify().
Wenn der Server die Bereinigungsverarbeitung beendet hat, wird der Thread zum Herunterfahren aktiviert.
Der Shutdown-Thread ruft nach zwei (2) Sekunden Verzögerung System.exit(0)
auf, um die Java Virtual Machine zu beenden. Die Verzögerung ist so, dass Nachrichten vom Server an den initiierenden Client die Reise vervollständigen.
Nein, interrupt()
funktioniert hier nicht, da RMI die Blockierung java.io
verwendet, die nicht unterbrechbar ist.
Sie können entweder einen anderen RMI-Aufruf an den Server in einem separaten Thread senden, der it anfordert, die Verarbeitung des Aufrufs programmgesteuert zu unterbrechen (vorausgesetzt, der serverseitige Code führt eine unterbrechbare Schleife aus eine Art).
Alternativ können Sie den ursprünglichen RMI-Aufruf in einem separaten Thread ausführen, den Sie bei Bedarf "verwerfen" können. Die Verwendung von java.util.concurrant.ExecutorService
würde hier nützlich erscheinen, da Sie eine Aufgabe senden und auf eine begrenzte Zeit warten können. Der eigentliche RMI-Aufruf würde nicht unterbrochen, aber Ihr Client-Programm könnte weiterhin fortfahren.
Dies scheint eine RMI fehlende Funktion zu sein.
Sie können jedoch Ihre eigene Socket-Factory implementieren, die von RMI verwendet werden soll, und die Sockets abbrechen. Ich erinnere mich, dass einige meiner Freunde es manuell gemacht haben, aber ich habe gerade eine Unterbrechungsbibliothek gefunden, die dieses Problem automatisch anspricht. Probieren Sie es aus und sagen Sie uns, wie es funktioniert.
java.util.concurrant ist eindeutig ein Tippfehler, der sein sollte java.util.concurrent.
Aber was noch wichtiger ist: Ich sehe java.util.concurrent.ExecutorService nirgendwo. Meintest du java.util.concurrent.ExecutorCompletionService?