thread.interrupt()
不会停止线程,它用于多线程程序的协调。除非您确切知道自己在做什么,否则不要使用它。RuntimeException
通常会终止线程,但不一定终止程序。System.exit(int)
几乎总是终止程序并返回状态码。System.exit(int)
可能无法真正停止程序。相反,Runtime.getRuntime().halt(int)
总是能够停止程序。很抱歉,您的第一句话是错误的。Thread.currentThread().interrupt()
不会停止线程或程序。
中断线程是一种向其发出信号以应该停止的方式,但这是一种合作的努力:线程中的代码应该定期检查已中断的状态,并且(在大多数情况下 - 但即使这也只是可选项)如果被中断应该停止。如果它不这样做,什么也不会发生。
具体来说,中断一个线程(任何线程,包括当前正在执行的线程)只会设置“已中断”标志。标准库中的某些方法将抛出InterruptedException,但这也只是一种信号,表示线程已被中断。在这种情况下应该做什么取决于运行在该线程中的代码。终止当前正在运行的Java虚拟机。参数用作状态码;按照惯例,非零状态代码表示异常终止。
因此调用exit()
(几乎)肯定会停止您的程序。与抛出RuntimeException
(或Error
)相比,这不能在调用堆栈的某个位置捕获,并且也不取决于是否有其他线程正在运行。另一方面,未捕获的异常会终止抛出它的线程,但如果存在任何其他(非守护程序)线程,则程序将继续运行。
与抛出异常的另一个区别是,exit()
不会向控制台打印任何内容(与未捕获的异常一样),而是使程序返回特定的状态码。状态码有时用于shell或批处理脚本,但除此之外,它们并不是非常有用。
为了完整起见,我想指出退出Java程序的第三种可能性。当调用System.exit(int)
(或以其他方式结束程序)时,运行时会在Java虚拟机停止之前进行一些清理工作。这在Runtime.exit(int)的Javadoc中有描述(由System.exit(int)
调用):
虚拟机的关闭序列包括两个阶段。在第一阶段中,所有已注册的关闭挂钩(如果有)将以某种未指定的顺序启动,并允许并发运行,直到它们完成。在第二阶段中,如果启用了退出时终结,则运行所有未调用的终结器。完成这些操作后,虚拟机就会停止。
如果任何一个关闭挂钩或终结器被阻止完成,例如因为死锁,程序可能永远无法退出。唯一保证JVM停止的方法是Runtime.halt(int):
应该极度谨慎地使用此方法。与exit方法不同,此方法不会启动关闭挂钩,并且如果启用了终止时运行未调用的终结器,则不会运行未调用的终结器。
如果还有其他(非守护线程)正在运行,停止主线程不会使JVM退出。System.exit()将终止所有其他线程。
Thread.currentThread().interrupt()
只会中断当前正在执行的线程,但是其余线程将继续运行,即使您的主线程被中断。System.exit(0)
会导致系统结束。所有线程都将被终止。Thread.currentThread().interrupt()
只会在当前线程上设置中断标志位,但不会停止该线程。 - Gray