Runtime.exec() - Performance / Frage zu Threads

Mr.Radar

Mitglied
Folgende Frage:

mein Code:

Java:
private JLabel lStatusMsg = new JLabel("bla");
private JTextField txtPathToFile = new JTextField(20);
txtPathToFile.setText("blabla.backup");

ActionListener alStartClick = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			lStatusMsg.setText("Führe Restore aus...");
			if(txtPathToFile.getText().length()==0) lStatusMsg.setText("Wählen sie eine Datei aus!");
			else {
				Runtime rt = Runtime.getRuntime();
				try {
					Process proc = rt.exec("cmd /C luxorgrestore.bat \""+txtPathToFile.getText()+"\"");
				    BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
				    String line;
				    while((line = br.readLine())!=null) {
				    	System.out.println(line);
				    }
					proc.waitFor();
					
					lStatusMsg.setText("Restore erfolgreich.");
				}
				catch(Exception ex) {
					lStatusMsg.setText("Fehler beim Restore!");
					ex.printStackTrace();
				}
			}	
		}
	};

(im Batchfile wird pg_restore (PostgreSQL) aufgerufen)

Ich habe das Gefühl, dass gegenüber des direkten Aufrufs des Batchfiles v.d. commandline aus, mein Code langsamer ist - hab ich hier irgendwo ein Performance-Bottleneck eingebaut, oder ist exec() generell etwas langsamer? (Falls es am InputStream liegen sollte: den brauch ich an sich nicht, nur wenn ich ihn nicht auslese, funktioniert die Batchausführung nicht richtig: pg_restore läuft laut taskmgr, aber terminiert nicht)


Weitere Frage: Das Setzen des Textes von lStatusMsg funktioniert nicht richtig - ich vermute, dass es einfach nicht vor rt.exec() aufgerufen wird (ich weiß, SWING ist nicht threadsafe). Als absoluter Noob in diesem Bereich - wie kann ich sicherstellen, dass lStatusMsg sicher vor dem Aufruf von rt.exec() geändert wird?
 
Nein, mit exec ist es nicht langsamer. Das OS forked einen Prozess, wie dieser Prozess gestartet wurde ist erstmal unerheblich.
Weitere Frage: Das Setzen des Textes von lStatusMsg funktioniert nicht richtig - ich vermute, dass es einfach nicht vor rt.exec() aufgerufen wird (ich weiß, SWING ist nicht threadsafe). Als absoluter Noob in diesem Bereich - wie kann ich sicherstellen, dass lStatusMsg sicher vor dem Aufruf von rt.exec() geändert wird?
Doch, es wird zuerst aufgerufen, schließlich steht es vor dem exec aufruf. Dein Problem ist das du den Event Dispatcher Thread hiermit blockierst:
while((line = br.readLine())!=null) {
System.out.println(line);
}
proc.waitFor();
Solange der Thread blockiert ist deine Oberfläche eingefroren und die Änderung kann nicht gezeichnet werden (und Benutzer werden sich fragen ob dein Programm abgestürzt ist).
Long Running Task (alles das länger als einige Millisekunden dauert) müssen in einem Background Thread ausgeführt werden.
 
Nein, mit exec ist es nicht langsamer. Das OS forked einen Prozess, wie dieser Prozess gestartet wurde ist erstmal unerheblich.
Da widerspreche ich vorsichtig. Wenn man eine Konsole unter Windows offen hat, dann läuft der Kommandozeileninterpreter bereits. Starten einer Batch-Datei aus der Konsole startet meines Wissens nach keinen neuen Prozess.

Ebenius
 
Da widerspreche ich vorsichtig. Wenn man eine Konsole unter Windows offen hat, dann läuft der Kommandozeileninterpreter bereits. Starten einer Batch-Datei aus der Konsole startet meines Wissens nach keinen neuen Prozess.
Ja und nein. Es mag etwas länger dauern den Prozess zu starten, aber das heißt nicht das er langsamer läuft (und die Startup Zeit dürfte konstant also im O Kalkül vernachlässigbar sein).
 

Zurück
Oben