2009-01-22 22 views
7

He creado un programa que busca archivos en una carpeta fuente. Si encuentra algún archivo, procesa ese archivo y lo mueve a una carpeta de destino, luego busca un nuevo archivo en la carpeta de origen. Tiene que seguir comprobando la carpeta fuente de un archivo.¿Cómo reiniciar el hilo en java?

He utilizado un hilo para buscar archivos en la carpeta de origen. El problema al que me enfrento es que cuando se lanza una excepción durante el procesamiento del archivo, el hilo se detiene. Quiero que el hilo se ejecute incluso si se lanza una excepción. Tiene que mover el archivo que causó el error a alguna otra carpeta y buscar un nuevo archivo en la carpeta de origen. ¿Cómo puedo hacer que el hilo siga funcionando?

Ej:

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

public void searchfile(){ 
    ... 
} 

actualización:

que debería ser más claro en mi pregunta. En realidad, hay 4 carpetas de origen y 4 carpetas de destino. Tengo que realizar la misma operación en cada par de destino & de origen. Así que he creado 4 hilos en una clase y hago la operación en una clase separada.

class MainClass 
{ 
    public static void main(String[] args){ 
     for(int i=0;i<4;i++){ 
     SearchClass search = new SearchClass(); 
     Thread thread = new Thread(search); 
     thread.start(); 
    } 
    } 
} 

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

public void searchfile(){ ... } } 

No se detiene la ejecución de todo el hilo aunque haya detectado una excepción en el centro. ¿Cómo puedo hacer eso?

Respuesta

14

Si un hilo se está muriendo debido a una excepción no detectada, la respuesta es simple: capture la excepción en un lugar apropiado para que pueda continuar. Capture la excepción dentro de su método searchfile o haga que el método run invoque searchfile en un bucle.

1

Dentro de su captura, puede mover el archivo a la carpeta de error, luego crear un nuevo objeto del mismo subproceso y volverlo a iniciar.

1

menos te tengo mal, su código no se encuentra la naturaleza "seguir funcionando", es decir, es necesario tener un bucle en alguna parte:

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 
    } 

} 

nota que esto es sólo una extensión muy simple de su ejemplo. todavía falta la parametrización de SearchTask para ser realmente específico para una carpeta, manejo de archivos & excepciones, etc. como se menciona en respuestas anteriores, su SearchTask debe implementar Runnable (prefiero que se llame ...), y en mi humilde opinión siempre es mejor utilizar un ExecutorService que generar hilos manualmente. Espero que esto ayude ...

0

dijiste que la excepción se puede lanzar durante el proceso de archivo, así que puse el processFile() en un bloque try-catch. pero si puede arrojarse durante la búsqueda, también puede ponerlo en una trampa de prueba.

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

Si desea que su hilo siga funcionando utilice un bucle.

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

Uy demasiado lento, pero 11 horas! –

0

Aquí están mis suposiciones basadas en su pregunta y su aclaración:

  • Cada hilo, en el método run(), sólo llama searchfile() una vez y no en un bucle
  • su método de searchfile() tiene una en él y desea que el bucle continúe ejecutándose incluso si se lanza una excepción en él.
  • que tienen alguna manera de inicializar cada hilo que no nos muestran (y que no es terriblemente importante para este quiestion específica)
  • searchfile() no declarar que lanza cualquier Exception
  • Usted no está utilizando un marco de registro, sino que están utilizando System.out (aunque el uso de un marco de registro es una muy buena idea
  • Java 5 está bien (si no usted tiene que utilizar un bucle for() diferente debajo

con estos assumpti complementos, que no quieren planificar para coger un Exception en su método de run() excepto para el propósito de la tala de que algo ha ido muy mal:

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

Tenga en cuenta que el código detecta RuntimeException. Siempre tome el Exception más específico que hará lo que necesita. A continuación, lo que necesita es algo como lo siguiente en su método searchfile():

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 
    } 
} 

Puesto que usted está atrapando inesperados Exception s en el bucle principal de su Thread, el hilo será continuar con el procesamiento después de manipular el Exception.

1

No estoy del todo seguro de si esto funcionará, pero aquí hay una oportunidad.

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

Puede ir fácilmente con una solución. Simplemente ejecute la lógica necesaria algunas veces y termine el trabajo según algunos criterios.

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; 
} 
} 

y la salida es

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 
Cuestiones relacionadas