Java线程停止,没有异常

时间:2012-08-13 01:31:06

标签: java multithreading

当我为我的程序使用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 个答案:

答案 0 :(得分:20)

请注意Error <{3}};这是一个Exception 因此,如果您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 for Error:

  

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

答案 1 :(得分:2)

  

无论如何都要找出他们为什么要停下来?

这有点棘手。

Java线程可以终止,原因有两个:

  • 它可以从run()方法返回
  • 它可以因为抛出异常而终止,而不会被捕获到线程的堆栈上。

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

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

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

  

无论如何都要重新启动线程吗?

没有。无法重新启动已终止的线程。

答案 2 :(得分:1)

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

请参阅An Introduction to Java Stack Traces

  

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

     

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

     

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

答案 3 :(得分:0)

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