Lassen Sie den übergeordneten Thread warten, bis der untergeordnete Thread abgeschlossen ist oder eine Zeitüberschreitung auftritt

Ich verwende einen Java-process unter Unix.

Ich muss einen externen process ausführen, der vom Hauptprozess mit ProcessBuilder erzeugt wird. Der Hauptprozess wartet, bis der externe process abgeschlossen ist, und startet dann den nächsten externen process. Ich habe es bis hier funktioniert.


public static void main(String[] args) { for(...) { int exitVal = runExternalProcess(args); if(exitVal !=0) { failedProcess.add(args); } } } private int runExternalProcess(String[] args) { ProcessBuilder pb = new ProcessBuilder(args[0], args[1], args[2]); pb.redirectErrorStream(true); Process proc = pb.start(); BufferedReader br = new BufferedReader(new InputStreamReader( proc.getInputStream())); String line = null; while ( (line = br.readLine()) != null) LOG.log(Level.SEVERE, line); //Main thread waits for external process to complete. //What I need to do is. // If proc.executionTime() > TIMEOUT // kill proc; int exitVal = proc.waitFor(); proc.getInputStream().close(); proc.getOutputStream().close(); proc.getErrorStream().close(); return exitVal; }

public static void main(String[] args) { for(...) { int exitVal = runExternalProcess(args); if(exitVal !=0) { failedProcess.add(args); } } } private int runExternalProcess(String[] args) { ProcessBuilder pb = new ProcessBuilder(args[0], args[1], args[2]); pb.redirectErrorStream(true); Process proc = pb.start(); BufferedReader br = new BufferedReader(new InputStreamReader( proc.getInputStream())); String line = null; while ( (line = br.readLine()) != null) LOG.log(Level.SEVERE, line); //Main thread waits for external process to complete. //What I need to do is. // If proc.executionTime() > TIMEOUT // kill proc; int exitVal = proc.waitFor(); proc.getInputStream().close(); proc.getOutputStream().close(); proc.getErrorStream().close(); return exitVal; }

 public static void main(String[] args) { for(...) { int exitVal = runExternalProcess(args); if(exitVal !=0) { failedProcess.add(args); } } } private int runExternalProcess(String[] args) { ProcessBuilder pb = new ProcessBuilder(args[0], args[1], args[2]); pb.redirectErrorStream(true); Process proc = pb.start(); BufferedReader br = new BufferedReader(new InputStreamReader( proc.getInputStream())); String line = null; while ( (line = br.readLine()) != null) LOG.log(Level.SEVERE, line); //Main thread waits for external process to complete. //What I need to do is. // If proc.executionTime() > TIMEOUT // kill proc; int exitVal = proc.waitFor(); proc.getInputStream().close(); proc.getOutputStream().close(); proc.getErrorStream().close(); return exitVal; } 

public static void main(String[] args) { for(...) { int exitVal = runExternalProcess(args); if(exitVal !=0) { failedProcess.add(args); } } } private int runExternalProcess(String[] args) { ProcessBuilder pb = new ProcessBuilder(args[0], args[1], args[2]); pb.redirectErrorStream(true); Process proc = pb.start(); BufferedReader br = new BufferedReader(new InputStreamReader( proc.getInputStream())); String line = null; while ( (line = br.readLine()) != null) LOG.log(Level.SEVERE, line); //Main thread waits for external process to complete. //What I need to do is. // If proc.executionTime() > TIMEOUT // kill proc; int exitVal = proc.waitFor(); proc.getInputStream().close(); proc.getOutputStream().close(); proc.getErrorStream().close(); return exitVal; }

Was ich nicht herausfinden kann, ist, wie man das macht. Bei einigen Eingaben hängt der externe process und in solchen Fällen möchte ich auf eine festgelegte Zeitüberschreitung warten. Wenn der externe process bis dahin nicht abgeschlossen ist, kill er einfach ab und übergebe die Kontrolle an den Hauptprozess (zusammen mit dem Ausgangswert, damit I kann die fehlgeschlagenen processe nachverfolgen), so dass der nächste externe process gestartet werden kann.

Ich versuchte proc.wait (TIMEOUT) und dann proc.exitValue (); um den Ausgangswert zu erhalten, aber es konnte nicht funktionieren.

Vielen Dank!

Sie können Thread.join (long) oder Thread.join (long, int) ausführen und den process in einem separaten Thread starten.

Hinzufügen von Code (functioniert aber nicht vollständig mit allen Ecken Fällen getestet)

  public class Test { public static void main(String[] args) throws Throwable { for(int i = 0; i < 3; i++) { ProcessRunner pr = new ProcessRunner(args); pr.start(); // wait for 100 ms pr.join(100); // process still going on? kill it! if(!pr.isDone()) { System.err.println("Destroying process " + pr); pr.abort(); } } } static class ProcessRunner extends Thread { ProcessBuilder b; Process p; boolean done = false; ProcessRunner(String[] args) { super("ProcessRunner " + args); // got lazy here :D b = new ProcessBuilder(args); } public void run() { try { p = b.start(); // Do your buffered reader and readline stuff here // wait for the process to complete p.waitFor(); }catch(Exception e) { System.err.println(e.getMessage()); }finally { // some cleanup code done = true; } } int exitValue() throws IllegalStateException { if(p != null) { return p.exitValue(); } throw new IllegalStateException("Process not started yet"); } boolean isDone() { return done; } void abort() { if(! isDone()) { // do some cleanup first p.destroy(); } } } }