11

当我为我的程序使用 4 个线程时,通常没有问题,但今天我将它增加到 8 个,我注意到 1-3 个线程停止工作而没有抛出任何异常。有没有办法找出他们停下来的原因?反正有没有让线程重新启动?

这就是我的线程的结构

public void run()
{
  Main.logger.info(threadName + ": New Thread started (inside run)");
  while (true)
  {
    try
    {
      //all my code
      //all my code
      //all my code
    }
    catch(Exception e)
    {
      Main.logger.error("Exception: " + e);
      try
      {
        Thread.sleep(10000);
      }
      catch (InterruptedException e1)
      {
        e1.printStackTrace();
      }
    }
    finally
    {               
      try
      {
        webClient.closeAllWindows();
        Thread.sleep(3000); 
        Main.logger.info(threadName + ": Closed browser!");
      }
      catch (Exception e)
      {
        Main.logger.error("Exception: " + e);
      }
    }  
  }// end while
}

问候!

4

4 回答 4

23

注意anError不是; _ Exception这是一个Throwable
所以,如果你catch ExceptionErrors仍然会通过:

private void m() {    
    try {
        m(); // recursively calling m() will throw a StackOverflowError
    } catch (Exception e) {
        // this block won't get executed, 
        // because StackOverflowError is not an Exception!
    }
}

要捕捉“一切”,请将您的代码更改为:

try {
    ...
} catch (Throwable e) {
   // this block will execute when anything "bad" happens
}


请注意,如果发生错误,您可能无能为力。错误的 javadoc 摘录:

Error 是 Throwable 的子类,表示合理的应用程序不应尝试捕获的严重问题。大多数此类错误是异常情况。ThreadDeath 错误虽然是“正常”情况,但也是 Error 的子类,因为大多数应用程序不应该尝试捕获它。

于 2012-08-13T02:14:56.713 回答
2

有没有办法找出他们停下来的原因?

这有点棘手。

Java 线程可能因两个原因而终止:

  • 它可以从它的run()方法返回,
  • 它可以由于抛出异常而不是在线程的堆栈中捕获而终止。

run()您可以通过对线程使用“UncaughtExceptionHandler”来检测后一种情况,但除非您修改线程的方法以记录事件......或类似的东西,否则无法肯定地检测到前一种情况。

我想,弄清楚发生了什么的另一种方法是将调试器附加到 JVM 并让它向您报告未捕获的异常。

(我怀疑您没有看到任何异常的原因是您的线程的run方法没有捕获/记录所有异常,并且它们没有未捕获的异常处理程序。)

反正有没有让线程重新启动?

不,没有办法重新启动已终止的线程。

于 2012-08-13T01:39:16.463 回答
1

如果您从命令行运行,您可以将所有线程的状态转储到控制台。在 Windows 上,您可以通过在 linux 下按 Ctrl+Break 来执行此操作,方法是使用 'kill' 向进程发送 QUIT 信号。

请参阅Java 堆栈跟踪简介

向 Java 虚拟机发送信号 在 UNIX 平台上,您可以使用 kill 命令向程序发送信号。这是退出信号,由 JVM 处理。例如,在 Solaris 上,您可以使用命令 kill -QUIT process_id,其中 process_id 是 Java 程序的进程号。

或者,您可以在启动 Java 程序的窗口中输入键序列 \。发送此信号指示 JVM 中的信号处理程序以递归方式打印出有关 JVM 内部线程和监视器的所有信息。

要在 Windows 95 或 Windows NT 平台上生成堆栈跟踪,请在运行 Java 程序的窗口中输入键序列,或单击窗口上的关闭按钮。

于 2012-08-13T01:38:38.363 回答
0

其中一个的线程优先级可能太高,尝试将它们设置为相同级别吗?如果它们之间存在任何控制,则可能发生死锁。

于 2012-08-13T02:48:04.807 回答