Java 线程停止,没有异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11927248/
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-31 06:57:58  来源:igfitidea点击:

Java thread stops with no Exception

javamultithreading

提问by Arya

When I use 4 threads for my program there is usually no problems, but today I increased it to 8 and I noticed 1-3 threads stop working without throwing any exceptions. Is there anyway to find out why they are stopping? is there anyway to make the thread restart?

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

This is how the structure of my thread is

这就是我的线程的结构

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
}

Regards!

问候!

回答by Bohemian

Note that an Erroris notan Exception; it's a Throwable.
So, if you catch Exception, Errorswill still get through:

请注意,Error不是一个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!
    }
}

to catch "everything", change your code to this:

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

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


Note that there might be little you can do if an Error occurs. Excerpt from javadoc for Error:


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

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.

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

回答by Stephen C

Is there anyway to find out why they are stopping?

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

That's a bit tricky.

这有点棘手。

A Java thread can terminate for two reasons:

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

  • it can return from its run()method,
  • it can terminate due to an exception being thrown and not caught on the thread's stack.
  • 它可以从它的run()方法中返回,
  • 它可能会因抛出异常而未在线程堆栈中捕获而终止。

You can detect the latter case by using an "UncaughtExceptionHandler" for the thread, but the former case can't be positively detected unless you modify your thread's run()method to log the event ... or something like that.

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

I guess, the other way to figure out what is going on would be to attach a debugger to the JVM and get it to report the uncaught exception to you.

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

(I suspect that the reason you are not seeing any exceptions is that your threads' runmethods are not catching / logging all exceptions, AND they don't have an uncaught exception handler.)

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

is there anyway to make the thread restart?

有没有办法让线程重新启动?

No. There is no way to restart a Thread that has terminated.

不可以。无法重新启动已终止的线程。

回答by Dmitry B.

If you are running from the command line, you can have dump states of all threads to the console. On windows you do this by hitting Ctrl+Break, under linux, by sending the QUIT signal to the process with 'kill'.

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

Please refer to An Introduction to Java Stack Traces

请参考Java Stack Traces 简介

Sending a signal to the Java Virtual Machine On UNIX platforms you can send a signal to a program by using the kill command. This is the quit signal, which is handled by the JVM. For example, on Solaris you can use the command kill -QUIT process_id, where process_id is the process number of your Java program.

Alternatively you can enter the key sequence \ in the window where the Java program was started. Sending this signal instructs a signal handler in the JVM, to recursively print out all the information on the threads and monitors inside the JVM.

To generate a stack trace on Windows 95, or Windows NT platforms, enter the key sequence in the window where the Java program is running, or click the Close button on the window.

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

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

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

回答by nicephotog

Thread priority on one of them could be too high, try setting them the same level through? Deadlocking is possible if there is any control on each and other between them.

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