【问题标题】:How do I respawn threads if they die如果线程死了,我如何重生线程
【发布时间】:2013-12-12 22:03:15
【问题描述】:

我有多个类型的多个线程(不同的类)。我希望以防其中一个抛出异常并被另一个新线程替换。我知道连接线程功能,但是我将如何为 5 种不同类型的线程实现它们,例如如果类型 1 线程死亡立即被替换,而不必等待类型 2 首先死亡。

这是一些示例伪代码。

class1 implements runnable{
  void run(){
     try{
       while(true){
         repeat task
        }
     } catch(Exception e){
      log error
     }
  }
}


class2 implements runnable{
  void run(){
     try{
       while(true){
         repeat task
        }
     } catch(Exception e){
      log error
     }
  }
}


class3 implements runnable{
  void run(){
     try{
       while(true){
         repeat task
        }
     } catch(Exception e){
      log error
     }
  }
}

public main(){

 // start all threads .start()
}

【问题讨论】:

  • 不要子类化 Thread,实现 Runnables 并使用 Executor 执行它们(参见 Executors)。
  • @isnot2bad,我很难理解你的意思。能给我举个例子吗?
  • 您能否添加一些代码,以便我们知道线程在其运行方法中正在做什么?他们为什么会“死”,死后会发生什么。
  • @isnot2bad 我进行了编辑。请检查一下。
  • 在这个时代,管理自己的线程太辛苦了。看看akka.io 什么的。让框架来管理线程并专注于您的任务。

标签: java multithreading


【解决方案1】:

我希望万一他们中的一个抛出异常并死掉以被另一个新线程替换。

我不太明白你为什么不能这样做:

public void run() {
   // only quit the loop if the thread is interrupted
   while (!Thread.currentThread().isInterrupted()) {
      try {
         // do some stuff that might throw
         repeat task;
      } catch (Exception e) {
         // recover from the throw here but then continue running
      }
   }
}

为什么需要重新启动一个新线程?仅仅因为一项任务引发了异常并不意味着它在某种程度上已经损坏并且它需要一个新的才能正常工作。如果您试图捕获所有异常(包括RuntimeException),那么catch (Exception e) 将执行此操作。如果你想真的小心点,你甚至可以捕捉到Throwable,以防有可能生成Errors——这种情况比较少见。

如果您实际上有多个任务(或者真的在处理线程的任何时候),您应该考虑使用ExecutorService 类。请参阅Java tutorial

// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
// define your jobs somehow
threadPool.submit(new Class1());
threadPool.submit(new Class2());
...
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();

因此,与其分叉一个线程来执行多个任务,不如启动一个线程池,它会根据需要启动线程来完成一堆任务。如果一个任务失败了,你当然可以向池中提交另一个任务,尽管这是一个有点奇怪的模式。

如果你想等待所有任务完成你会使用:

threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);

【讨论】:

  • 这个“重启线程”是一个反复出现的主题。我想知道哪本书/网站从未听说过循环?此类资源需要在更多开发人员之前消灭。被感染。
  • 不知道@MartinJames。可能是 C 的保留,内存可能处于某种不稳定状态或其他什么?
【解决方案2】:
布尔应该停止(){ // 考虑如何/何时停止是个好主意;) 返回假; } 无效的runThreadGivenType(最终可运行的taskToRun){ 新线程() { @覆盖 公共无效运行(){ 尝试 { taskToRun.run(); } 最后 { 如果(!应该停止()){ runThreadGivenType(taskToRun); } } } }。开始(); } public void main(String[] args) 抛出异常 { runThreadGivenType(new Runnable() { public void run() { System.out.println("我几乎是不死线程!"); throw new RuntimeException(); } }); TimeUnit.SECONDS.sleep(10); }

考虑使用执行器来管理线程池也是一个好主意。普通的、[un/hand] 管理的线程不是最佳实践;)

【讨论】:

    猜你喜欢
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    相关资源
    最近更新 更多