ewig laufendes Javaprogramm ("Service")

dermoritz

Bekanntes Mitglied
ich bastele gerade an einer Art Dienstprogramm welches bestimmte Dateioperationen macht. Das Dienstprogramm selbst soll ewig laufen (wie ein Systemdienst). Nur wie implementiert man so was?
Bzw. schrecke ich vor einer while(true bzw. bis dienst gestoppt)-Schleife in meiner main() zurück? Ist meine Sorge berechtigt? Wie machen es andere Dienstprogramme? Oder Gui Anwendungen? Haben die auch innere while(bis beende mich)-schleifen?

Oder kann man das ganze ereigniss gesteuert bauen - "schlafe solange nix passiert"?!
 
Bzw. schrecke ich vor einer while(true bzw. bis dienst gestoppt)-Schleife in meiner main() zurück?
Wieso, das willst du doch eigentlich?
Naja, ein sleep oder ähnlich sollte man schon drinnen haben 😉

Wie machen es andere Dienstprogramme? Oder Gui Anwendungen? Haben die auch innere while(bis beende mich)-schleifen?
Ja, die haben auch so eine Schleife.
 
Selbst bei dem "schlafe solange nix passiert", brauchst du ja einen Teil, der ewig läuft. Es wird im Endeffekt immer auf eine Endlosschleife hinauslaufen. Da brauchst dir aber keinen Kopf machen, die Beendigungsbedingung musst du halt nur richtig setzen, sonst musst du den Prozess jedes Mal killen, wenn das Teil doch mal gestoppt werden soll
 
vielen dank

ich hatte nur sorge, dass die while(richtige Bedingung) schleife mit maximaler Geschwindigkeit läuft - einen Kern auslastet - auch wenn nix zu tun ist?!
aber das ist nicht so, oder? - so schlau ist die vm?
 
ich hatte nur sorge, dass die while(richtige Bedingung) schleife mit maximaler Geschwindigkeit läuft - einen Kern auslastet - auch wenn nix zu tun ist?!
aber das ist nicht so, oder? - so schlau ist die vm?
Wenn da kein sleep drinnen steckt dann hast du 1 CPU voll ausgelastet, so schlau musst du schon selber sein, die VM führt nur den Code aus.
 
Entweder musst du auf einen Status zur Verarbeitung pollen, was man klugerweise nicht ständig macht sondern in bestimmten Intervallen, oder du lässt dich (wenn möglich) benachrichtigen, z.B. über einen Listener- oder Observer-Mechanismus.
 
das heißt das "andere" Programme auch keine while(bedingung) schleife benutzen, sonst hätten sie ja so viel cpu last - so hab ichs mir ja gedacht.

nun ist die Frage wie es andere Programme machen z.B. die Swing gui, oder der Tomcat dienst - wie sieht bei ewig laufenden java-Programmen die main() aus? Sind da sleeps drine die auf ereignisse reagieren?

insbesondere wie sieht der mechanismus zum stoppen der anwendung aus?

Polling ist glaube diesbezüglich auch nicht optimal - "alle 10s prüfen ob jemand stop gedrückt hat". Dann wartet man im dümmsten Fall bis die Anwendung reagiert.
 
das heißt das "andere" Programme auch keine while(bedingung) schleife benutzen, sonst hätten sie ja so viel cpu last - so hab ichs mir ja gedacht.
Nein, das heisst nur dass du nicht richtig liest, siehe meine erste Antwort.
 
Es wird im Endeffekt immer auf eine Endlosschleife hinauslaufen.

Das erinnert mich an die aktuelle Werbung: "Und nie mehr endet... wann?" - "Ähm... nie mehr...?!"
scnr 😀

@dermoritz: Endlosschleifen sind nur dann so richtig schlecht, wenn sie wirklich endlos laufen...
Ansonsten passiert das in Java viel, zB um Fenster offen zu halten: "Mach das, solange das Fenster nicht geschlossen wird"
 
eigentlich hab ich eure antworten alle gelesen, dass Problem war sie so zu verstehen, dass sie sich nicht widersprechen. Bzw. gabs in 3 Antworten ca. 5 Bausteine. ICh versuche nocheinmal eine Zusammenfassung:

Eine BLANKE while(!stop)-Schleife ist schlecht da 100% CPU Last. Man braucht unbedingt ein sleep. Mit einem sleep hat nun 2 Logiken: nach wie vor die eine die irgendwann "stop" setzt - dazu muss die while-Schleife in einem anderen Thread laufen oder (http://www.java-forum.org/allgemeine-java-themen/108576-api-methode-immer-laeuft-stop-gerufen.html)?
Zweitens braucht man nun einen Aufwachmechanismus - noch ein Grund warum das while und das sleep in einem anderen thread laufen sollen.

der Aufwachmechanismus ist genau das was mir nicht klar ist, wie man das implementiert. Ich würde das gerne rein eventbasiert machen (wie ich oben geschrieben habe). Wie macht man sowas? (Events kenne ich bisher nur aus Swing-Anwendungen)
Mich würde brennend die Struktur einer solchen Main-Methode interessieren - da sollte es doch Beispiele geben?
 
Die main-Methode ist völlig irrelevant. Es kommt darauf an, was welcher Thread macht.

Beispiel:
dein Service mach "Dateioperationen". Du trägst einen Job in einen Scheduler ein, der regelmäßig bestimmte Ereignisse auf dem Dateisystem überprüft, die dich dazu veranlassen sollen etwas zu tun. Wenn ein solches Ereignis eingetreten ist, wird eine Aktion getriggert, sonst passiert nichts.
ScheduledExecutorService (Java 2 Platform SE 5.0)

Wenn es nur den Haupthread und den Schedulerthread gibt, wird der Hauptthread auf das Ende des Schedulers warten, bzw. in einer Schleife die Ergebnisse des Schedulers auswerten und reagieren, da gibt es viele Möglichkeiten.

Pollen ist nicht schlecht. Es kommt darauf an wie man es macht. Und das da unter der Haube Schleifen Thread#sleep, Thread#wait und Thread#notify ablaufen, ist völlig egal.
Sollte deine "Dateioperation" von selber Ereignisse emittieren, kann man direkt einen Listener dafür implementieren (oder einen Observer) und fertig.
 
Zuletzt bearbeitet:
Vielen Dank!

jetzt sehe ich langsam wohin die Reise geht - ich hatte gehofft, dass es für meinen use-case irgendein "high-level-konstrukt" gibt. Ich werde jetzt mal versuchen konkret zu beschreiben was mein Programm tut und wie ich es bisher umgesetzt habe - auch mit Hilfe aus diesem Forum (http://www.java-forum.org/allgemeine-java-themen/108576-api-methode-immer-laeuft-stop-gerufen.html):

also ich hab eine Klasse in der die Arbeit läuft (Ordner abarbeiten, wenn fertig warten bis neuer Ordner entsteht - "jNotify"). diese Arbeit läuft in einem separaten Thread mit while(!stop)-Schleife. Es gibt öffentliche Methoden Stop() und Start() die diese Schleife steuern (stop() setzt stop=true, start- startet den thread) - inziwschen funktioniert diese Steuerung auch über jmx.

Funktional ist das ganze also fertig die frage ist nur wie sieht die main-Methode dazu aus. Diese soll eben nur ewig laufen und nix tun außer das Start und Stop über jmx bereitstellen. Natürlich wäre ein "shutdown" auch nicht schlecht: stop(); return; (sich selbst beenden aber vorher warten bis stop() ausgeführt wurde).

Die Frage ist ob für diesen Use-Case "ScheduledExecutorService" geeignet ist. Die einzigen Ereignisse wären das Aufrufen von Methoden über JMX?! Deswegen finde ich polling ungünstig - entweder muss der benutzer warten bis das Programm reagiert oder man pollt zu oft - im schnitt pollt man eh viel zu oft (das Programm soll Wochen Monate laufen ohne das ein User irgendwas macht)

Die Alternativen von die Fart versthe ich leider noch weniger: "Thread#sleep, Thread#wait und Thread#notify" und "... implementieren (oder einen Observer) und fertig"

Wie sieht die Verwendung dieser Konstrukte in einem Beispiel oder Pseudecode aus? Gibt es irgendwo ein Beispiel (wonach googelt man) für eine ewig laufende, auf (user)-ereignisse wartende main()-methode?
 
also dank eures Stoßens in die richtige Richtung und viel rumgegoogle hab ich nun den "klassischen" Ansatz für dieses Problem gefunden: "wait/notify" - gibts wohl schon seit java 1, und inzwischen in einer multi-thread variante?!
Das ist super einfach:

Java:
...
public static void main(final String[] args){
...
new Thread(new Runnable() {
			
			@Override
			public void run() {
				synchronized (lock) {
					while (!shutdown) {
						try {
							MeinProzess prozess = MeinProzess.getInstance();
							prozess.starteProzess();
							lock.wait(); //!!!!
						} catch (InterruptedException e) { 
						}
					}
				}
			}
		}).start();

}
	public static void exit() {
		synchronized (lock) {
			shutdown = true;
			lock.notifyAll();
		}
	}
 
in dem fall ist das "gegenteil" von multi-threaded nicht single-threaded sondern - 2-threaded ;-).

also in java 5 gibts wohl was mit dem ich einen Haufen threads auf diese Arte (besser) synchronisieren kann.
 

Zurück
Oben