java - 在 Java 程序的主线程中调用 System.exit(0) 和 Thread.currentThread().interrupt() 有什么区别?

标签 java multithreading interrupt

两者都会导致程序停止执行。不过,很明显,这种情况的发生方式肯定存在一些差异。它们是什么?

最佳答案

总结

  1. thread.interrupt() 不会停止线程。它用于多线程程序中的协调。除非您确切知道自己在做什么,否则不要使用它。
  2. 抛出 RuntimeException 将(通常)终止线程,但不一定终止程序。
  3. System.exit(int) 几乎总是终止程序并返回状态码。
  4. 在不寻常的情况下,System.exit(int) 可能不会真正停止程序。另一方面,Runtime.getRuntime().halt(int) 总是这样。

线程中断

恐怕你的第一句话是错误的。 Thread.currentThread().interrupt() 不会停止线程或程序。

中断线程是表示它应该停止的一种方式,但这是一种合作努力:线程中的代码应该不时检查中断状态并且(在大多数情况下)情况下 - 但即使这只是可选的)如果被中断也应该停止。如果不这样做,什么都不会发生。

具体来说,中断一个线程(任何线程,包括当前正在执行的线程)只会设置 interrupted 标志。标准库中的某些方法会抛出 InterruptedException,但这也只是表示线程已被中断的一种方式。在这种情况下应该怎么做取决于该线程中运行的代码。

以下是 Brian Goetz 的 Java Concurrency in Practice 一书中的相关部分:

Thread provides the interrupt method for interrupting a thread and for querying whether a thread has been interrupted. Each thread has a boolean property that represents its interrupted status; interrupting a thread sets this status.

Interruption is a cooperative mechanism. One thread cannot force another to stop what it is doing and do something else; when thread A interrupts thread B, A is merely requesting that B stop what it is doing when it gets to a convenient stopping point if it feels like it.While there is nothing in the API or language specification that demands any specific application level semantics for interruption, the most sensible use for interruption is to cancel an activity. Blocking methods that are responsive to interruption make it easier to cancel long running activities on a timely basis.

异常和 System.exit(int)

Javadoc of System.exit(int)说:

Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.

所以调用 exit() 将(几乎)肯定会停止您的程序。与抛出 RuntimeException(或 Error)相比,这不能在调用堆栈的某个地方被捕获,并且它也不依赖于是否有其他线程在运行。另一方面,未捕获的异常会终止引发它的线程,但如果有任何其他(非守护程序)线程,程序将继续运行。

与抛出异常的另一个区别是 exit() 不会向控制台打印任何内容(就像未捕获的异常一样),而是使程序返回特定的状态代码。状态码有时用于 shell 或批处理脚本,但除此之外,它们不是很有用。

Runtime.halt(int)

最后(为了完整起见),我想指出退出 Java 程序的第三种可能性。当 System.exit(int) 被调用(或程序以某种其他方式结束)时,运行时会在 Java 虚拟机停止之前进行一些清理工作。这在 Runtime.exit(int) 的 Javadoc 中有描述。 (由 System.exit(int) 调用:

The virtual machine's shutdown sequence consists of two phases. In the first phase all registered shutdown hooks, if any, are started in some unspecified order and allowed to run concurrently until they finish. In the second phase all uninvoked finalizers are run if finalization-on-exit has been enabled. Once this is done the virtual machine halts.

如果任何关闭 Hook 或终结器无法完成,例如因为 deadlock ,程序可能永远不会真正退出。保证 JVM 停止的唯一方法是 Runtime.halt(int) :

This method should be used with extreme caution. Unlike the exit method, this method does not cause shutdown hooks to be started and does not run uninvoked finalizers if finalization-on-exit has been enabled.

关于java - 在 Java 程序的主线程中调用 System.exit(0) 和 Thread.currentThread().interrupt() 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12572456/

相关文章:

java - InternetExplorerDriver 上的异常

java - 在 Spring Batch 中生成多个异步作业后如何使主线程保持等待状态

java - 乐观锁 - Hibernate 的并发问题

c++ - STM32 NVIC ADC 中断未触发

c - AVR 中断的变量在 main 中更新

java - 为什么不能在 try 和 catch block 之间插入代码?

java - 从 Java 调用 GnuWin 命令还是有更好的方法?

linux - MSI 中断如何在 Linux 驱动程序中工作?

java - 在使用 JPA 映射类时,为什么有人要在 getter 或 setter 上添加注释?

java - Twilio 线程消息