2009-01-22 11 views
7

Ich habe ein Programm erstellt, das nach Dateien in einem Quellordner sucht. Wenn eine Datei gefunden wird, verarbeitet sie diese Datei und verschiebt sie in einen Zielordner. Anschließend sucht sie im Quellordner nach einer neuen Datei. Es muss weiterhin den Quellordner für eine Datei prüfen.Wie thread in Java neu starten?

Ich habe einen Thread verwendet, um nach Dateien im Quellordner zu suchen. Das Problem, auf das ich stoße, ist, wenn während der Dateiverarbeitung eine Ausnahme ausgelöst wird, der Thread gestoppt wird. Ich möchte, dass der Thread auch dann ausgeführt wird, wenn eine Ausnahme ausgelöst wird. Er muss die Datei, die den Fehler verursacht hat, in einen anderen Ordner verschieben und im Quellordner nach einer neuen Datei suchen. Wie kann ich den Thread weiterlaufen lassen?

ZB:

public void run() { 
    try { 
     searchfile(); 
    } 
    catch(Exception e) { 
     e.printStackTrace(); 
    } 
} 

public void searchfile(){ 
    ... 
} 

aktualisieren:

sollte ich in meiner Frage klarer sein. Eigentlich gibt es 4 Quellordner und 4 Zielordner. Ich muss die gleiche Operation in jedem Quell-& Ziel-Paar durchführen. Also habe ich 4 Threads in einer Klasse erstellt und mache die Operation in einer separaten Klasse.

Der Thread hört nicht auf zu laufen, obwohl er irgendeine Ausnahme in der Mitte gefangen hat. Wie kann ich das machen?

Antwort

14

Wenn ein Thread aufgrund einer nicht abgefangenen Ausnahme abstirbt, ist die Antwort einfach: Fangen Sie die Ausnahme an einem geeigneten Ort, damit Sie weitermachen können. Entweder fangen Sie die Ausnahme in Ihrer Suchdatei-Methode ab oder rufen Sie die Suchmethode der run-Methode in einer Schleife auf.

1

Innerhalb Ihres Catch können Sie die Datei in den Fehlerordner verschieben und dann ein neues Objekt desselben Threads erstellen und erneut starten.

1

Wenn ich dich nicht falsch verstanden wird Ihr Code das „Laufen halten“ Natur fehlt, das heißt Sie müssen irgendwo eine Schleife haben:

public static void main(String[] args){ 

    ExecutorService service = Executors.newFixedThreadPool(4); 

    // for each of your 4 folders 
    while (true) { 
     Future<File> searchResult = service.submit(new SearchTask()); 
     try { 
      File foundFile = searchResult.get(); 
      // handle found file 
     } catch (Exception e) { 
      // handle exception 
     } 
    } 
} 

private static class SearchTask implements Callable<File> { 

    @Override 
    public File call() { 
     return searchFile(); 
    } 

    public File searchFile() { 
     // search & return found file 
    } 

} 

beachten Sie, dass dies nur eine sehr einfache Erweiterung Ihres Beispiel. es fehlt noch die Parametrisierung der SearchTask, um tatsächlich für einen Ordner spezifisch zu sein, Handhabung von Dateien & Ausnahmen, wie in früheren Antworten erwähnt, sollte Ihre SearchTask Runnable implementieren (ich bevorzuge Callable ...), und IMHO ist es immer besser Verwenden eines ExecutorService als zum manuellen Erstellen von Threads. hoffe, das hilft ...

0

Sie haben gesagt, dass die Ausnahme während des Dateiprozesses ausgelöst werden kann, also setze ich die processFile() in einen try-catch-Block. aber wenn es während der Suche geworfen wird, können Sie es auch in einen Versuch-Fang setzen.

public void run() { 
    while(!terminated) {  
     findNextFile(); 
     try { 
      processFile(); 
     } catch { 
      // handle error 
     } 
    } 
} 
2

Wenn Sie möchten, dass Ihr Thread weiterläuft, verwenden Sie eine Schleife.

public void run() { 
    while(!Thread.interrupted()) 
     try { 
      searchfile(); 
     } 
     catch(Exception e) { 
      e.printStackTrace(); 
     } 
} 
+0

oops zu langsam, aber 11 Stunden! –

0

Hier sind meine Annahmen, auf Ihre Frage und Ihre Klarstellung zugrunde:

  • Jeder Thread, in dem run() Methode ruft nur searchfile() einmal und nicht in einer Schleife
  • Ihre searchfile() Methode a hat Schleife darin und Sie wollen diese Schleife weiter laufen, auch wenn eine Ausnahme in es geworfen wird.
  • Sie haben einen Weg jeden Thread initialisieren, dass Sie nicht uns zeigen (und das ist nicht sehr wichtig für diese spezifische quiestion)
  • searchfile() erklärt nicht, dass es irgendein Exception
  • werfen Sie sind nicht mit einem Logging-Framework, sondern stattdessen System.out mit (obwohl ein Logging-Framework eine wirklich gute Idee ist
  • Java 5 OK ist (sonst werden Sie eine andere for() Schleifen unter

Mit dieser assumpti verwenden müssen ons, Sie wollen, außer zum Zweck der Protokollierung nicht planen eine Exception in Ihrem run() Methode zu fangen, dass etwas sehr schief gelaufen ist:

public void run() { 
    try { 
     searchfile(); 
    } catch (RuntimeException e) { 
     System.out.println("Something went very wrong! Unexpected RuntimeException"); 
     e.printStackTrace(); 
    } 
} 

Beachten Sie, dass der Code RuntimeException fängt. Fange immer die spezifischsten Exception, die tun, was du brauchst. Dann, was Sie brauchen, ist etwas wie die folgenden in Ihrem searchfile() Methode:

File[] files = directory.listFiles(); 
for (File file : files) { 
    try { 
     // Do your normal file/directory processing here 
    } catch (Exception e) { 
     System.out.println("Exception processing file " + file.getName() + " " + e); 
     // Move "file" to another area 
    } 
} 

Da Sie unerwartete Exception s in der Hauptschleife Ihrer Thread sind Trapping, Ihre Thread-Verarbeitung fortgesetzt wird, nachdem die Exception Handhabung.

1

Ich bin mir nicht ganz sicher, ob das funktioniert, aber hier ist ein Versuch.

public void run() { 
    try { 
     searchFile(); 
    } catch(Exeption e) { 
     e.printStackTrace(); 
     if(!Thread.currentThread().isAlive()) 
      Thread.currentThread().start(); 
    } 
} 
0

Sie können problemlos mit einer Problemumgehung gehen. Führen Sie die erforderliche Logik für einige Zeit aus und beenden Sie den Job anhand einiger Kriterien.

public class ThreadRestartWorkaround extends Thread { 

public static void main(String[] args) { 
    ThreadRestartWorkaround th = new ThreadRestartWorkaround(5); 
    th.start(); 
} 

private int maxCycles; 
private int currentCycle; 

public ThreadRestartWorkaround(int maxCycles) { 
    this.maxCycles = maxCycles; 
} 

@Override 
public void run() { 
    while(executeSomeLogicUntilReachingTheLimit()); 
    System.out.println("Finished due to exceeding the maxCycles config"); 
} 

private boolean executeSomeLogicUntilReachingTheLimit() { 
    currentCycle++; 
    System.out.println("Executing logic for " + currentCycle + " time"); 
    return currentCycle < maxCycles; 
} 
} 

Und der Ausgang ist

Executing logic for 1 time 
Executing logic for 2 time 
Executing logic for 3 time 
Executing logic for 4 time 
Executing logic for 5 time 
Finished due to exceeding the maxCycles config