java 如何在java中重新启动线程?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/468266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 12:31:38  来源:igfitidea点击:

How to restart thread in java?

javamultithreadingexception

提问by raja

I have created a program which searches for files in a source folder. If it finds any file, it processes that file and moves it to a destination folder, then looks for a new file in the source folder. It has to keep on checking the source folder for a file.

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

I have used a thread to look for files in the source folder. The problem I am facing is whenever any exception is thrown during file processing, the thread gets stopped. I want the thread to be running even if an exception is thrown. It has to move the file that caused the error to some other folder and look for a new file in the source folder. How can I make the thread keep on running?

我使用了一个线程来查找源文件夹中的文件。我面临的问题是,只要在文件处理过程中抛出任何异常,线程就会停止。即使抛出异常,我也希望线程正在运行。它必须将导致错误的文件移动到其他文件夹并在源文件夹中查找新文件。如何让线程继续运行?

Eg:

例如:

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

public void searchfile(){
  ...
}


Update:

更新

I should be more clear in my question. Actually there are 4 source folders and 4 destination folders. I have to perform the same operation in each source & destination pair. So i have created 4 threads in one class and do the operation in separate class.

我的问题应该更清楚。实际上有 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(){ ... } }

All the thread wont stop running eventhough it caught any exception in middle. How can i do that?

即使在中间捕获任何异常,所有线程也不会停止运行。我怎样才能做到这一点?

回答by Jon Skeet

If a thread is dying due to an uncaught exception, the answer is simple: catch the exception at an appropriate place so that you can keep going. Either catch the exception within your searchfile method, or make the run method call searchfile in a loop.

如果线程由于未捕获的异常而死亡,答案很简单:在适当的位置捕获异常,以便您可以继续运行。要么在 searchfile 方法中捕获异常,要么让 run 方法在循环中调用 searchfile。

回答by Peter Lawrey

If you want your thread to keep running use a loop.

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

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

回答by John

I'm not entirely sure if this will work, yet here's a try.

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

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

回答by Bashar Kokash

Inside your catch, you can move the file to the error folder then create a new object of the same thread and start it again.

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

回答by Rahel Lüthy

unless i got you wrong, your code is missing the "keep running" nature, i.e. you need to have a loop somewhere:

除非我弄错了,否则您的代码缺少“继续运行”的性质,即您需要在某处有一个循环:

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
    }

}

note that this is just a very simple extension of your example. it is still missing the parametrization of the SearchTask to actually be specific for a folder, handling of files & exceptions, etc. as mentioned in previous answers, your SearchTask should implement Runnable (i prefer Callable...), and IMHO it's always better to use an ExecutorService than to spawn threads manually. hope this helps...

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

回答by Rahel Lüthy

you said that the exception may be thrown during file process , so i put the processFile()in a try-catch block. but if it may be thrown during search, you may put it in a try-catch too.

你说在文件处理过程中可能会抛出异常,所以我把它processFile()放在一个 try-catch 块中。但是如果它可能在搜索过程中被抛出,你也可以把它放在一个 try-catch 中。

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

回答by yurko

You can easily go with a workaround. Just run the needed logic for some amount of times and finish the job based on some criteria.

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

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

And the output is

输出是

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

回答by Eddie

Here are my assumptions based on your question and your clarification:

以下是我根据您的问题和您的澄清做出的假设:

  • Each thread, in the run()method, only calls searchfile()once and not in a loop
  • your searchfile()method has a loop in it and you want that loopto continue running even if an exception is thrown in it.
  • you have some way of initializing each thread that you aren't showing us (and that isn't terribly important for this specific quiestion)
  • searchfile()does not declare that it throws any Exception
  • You aren't using a logging framework, but are instead using System.out(although using a logging framework is a Really Good Idea
  • Java 5 is OK (otherwise you'll have to use a different for()loop below
  • 每个线程,在run()方法中,只调用searchfile()一次而不是在循环中
  • 您的searchfile()方法中有一个循环,并且即使在其中抛出异常,您也希望该循环继续运行。
  • 您有某种方法可以初始化您没有向我们展示的每个线程(这对于这个特定的问题并不是非常重要)
  • searchfile()不声明它抛出任何 Exception
  • 您没有使用日志记录框架,而是使用System.out(尽管使用日志记录框架是一个非常好的主意
  • Java 5 没问题(否则你必须在for()下面使用不同的循环

With these assumptions, you don't want to plan to catch an Exceptionin your run()method except for the purpose of logging that something went very wrong:

有了这些假设,您不想计划Exception在您的run()方法中捕获一个,除非是为了记录出现非常错误的情况:

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

Note that the code catches RuntimeException. Always catch the most specific Exceptionthat will do what you need. Then what you need is something such as the following in your searchfile()method:

请注意,代码捕获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
    }
}

Since you are trapping unexpected Exceptions in the main loop of your Thread, your thread will continue processing after handling the Exception.

由于您Exception在主循环中捕获了意外的s Thread,您的线程将在处理Exception.