如何在java中重启线程?

我创建了一个程序来搜索源文件夹中的文件。 如果找到任何文件,它会处理该文件并将其移动到目标文件夹,然后在源文件夹中查找新文件。 它必须继续检查文件的源文件夹。

我使用线程来查找源文件夹中的文件。 我面临的问题是,在文件处理期间抛出任何exception时,线程都会停止。 即使抛出exception,我也希望线程能够运行。 它必须将导致错误的文件移动到其他文件夹并在源文件夹中查找新文件。 如何让线程继续运行?

例如:

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

更新

在我的问题中我应该更清楚。 实际上有4个源文件夹和4个目标文件夹。 我必须在每个源和目标对中执行相同的操作。 所以我在一个类中创建了4个线程,并在单独的类中执行操作。

 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(){ ... } } 

所有的线程都不会停止运行,尽管它在中间发现任何exception。 我怎样才能做到这一点?

如果一个线程由于未捕获的exception而死亡,答案很简单:在适当的地方捕获exception,以便继续。 在searchfile方法中捕获exception,或者在循环中使run方法调用searchfile。

如果您希望线程继续运行,请使用循环。

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

在catch中,您可以将文件移动到error文件夹,然后创建同一线程的新对象并再次启动它。

除非我弄错了,你的代码缺少“保持运行”的性质,即你需要在某个地方有一个循环:

 public static void main(String[] args){ ExecutorService service = Executors.newFixedThreadPool(4); // for each of your 4 folders while (true) { Future searchResult = service.submit(new SearchTask()); try { File foundFile = searchResult.get(); // handle found file } catch (Exception e) { // handle exception } } } private static class SearchTask implements Callable { @Override public File call() { return searchFile(); } public File searchFile() { // search & return found file } } 

请注意,这只是您示例的一个非常简单的扩展。 它仍然缺少SearchTask的参数化实际上特定于文件夹,处理文件和exception等,如前面的答案所述,你的SearchTask应该实现Runnable(我更喜欢Callable ……),而恕我直言它总是更好使用ExecutorService而不是手动生成线程。 希望这可以帮助…

我不完全确定这是否有效,但这是一个尝试。

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

你说在文件处理期间可能抛出exception,所以我将processFile()放在try-catch块中。 但如果在搜索过程中可能会抛出它,你也可以把它放在试一试。

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

以下是基于您的问题和澄清的假设:

  • run()方法中的每个线程只调用一次searchfile()而不是循环
  • 你的searchfile()方法中有一个循环,你希望该循环继续运行,即使它中引发了exception。
  • 你有办法初始化你没有向我们展示的每个线程(这对于这个特定的静止并不是非常重要)
  • searchfile()不声明它会抛出任何Exception
  • 您没有使用日志框架,而是使用System.out (尽管使用日志框架是一个非常好的主意
  • Java 5没问题(否则你将不得不在下面使用不同的for()循环

有了这些假设,您不希望计划在run()方法中捕获Exception ,除非记录某些内容出错:

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

请注意,代码捕获RuntimeException 。 始终捕获最能满足您需求的Exception 。 那么你需要的是你的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 } } 

由于您正在Thread的主循环中捕获意外的Exception ,因此您的线程将在处理Exception后继续处理。

您可以轻松地使用解决方法。 只需运行所需的逻辑一段时间,然后根据某些标准完成工作。

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

输出是

 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