在 Java 程序的主线程中调用 System.exit(0) 和 Thread.currentThread().interrupt() 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12572456/
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
What are the differences between calling System.exit(0) and Thread.currentThread().interrupt() in the main thread of a Java program?
提问by brandones
Both cause a program to stop executing. It's clear that there must be some differences in how this happens, though. What are they?
两者都会导致程序停止执行。不过,很明显,这种情况的发生方式肯定存在一些差异。这些是什么?
回答by rolve
Summary
概括
thread.interrupt()
does not stop a thread. It is used for coordination in multi-threaded programs. Don't use it unless you know exactly what you do.- Throwing a
RuntimeException
will (usually) terminate the thread but not necessarily the program. System.exit(int)
almostalways terminates the program and returns a status code.- In unusual situations,
System.exit(int)
might not actually stop the program.Runtime.getRuntime().halt(int)
on the other hand, always does.
thread.interrupt()
不会停止线程。它用于多线程程序中的协调。除非您确切地知道自己在做什么,否则不要使用它。- 抛出一个
RuntimeException
遗嘱(通常)会终止线程,但不一定是程序。 System.exit(int)
几乎总是终止程序并返回状态代码。- 在异常情况下,
System.exit(int)
可能不会真正停止程序。Runtime.getRuntime().halt(int)
另一方面,总是如此。
Thread Interruption
线程中断
I'm afraid your first sentence is wrong. Thread.currentThread().interrupt()
does not stop the thread or the program.
恐怕你的第一句话是错误的。Thread.currentThread().interrupt()
不会停止线程或程序。
Interrupting a thread is a way to signal that it shouldstop, but this is a cooperative effort: The code in the thread is supposed to check the interrupted status from time to time and (in most cases - but even this is only optional) should stop if is has been interrupted. If it doesn't do that nothing will happen.
中断线程是一种通知它应该停止的方式,但这是一种合作的努力:线程中的代码应该不时检查中断状态并且(在大多数情况下 - 但即使这只是可选的)应该如果被中断,则停止。如果它不这样做,什么都不会发生。
Specifically, interrupting a thread (any thread, include the currently executing one) will only set the interruptedflag. Certain methods in the standard library will throw an InterruptedException, but this is also just a way to signal that the thread has been interrupted. What should be done in such a situation is up to the code running in that thread.
具体来说,中断一个线程(任何线程,包括当前正在执行的线程)只会设置中断标志。标准库中的某些方法会抛出一个 InterruptedException,但这也只是表明线程已被中断的一种方式。在这种情况下应该做什么取决于在该线程中运行的代码。
Here are the relevant parts from the Java Concurrency in Practicebook by Brian Goetz:
以下是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.
Thread 提供了中断线程和查询线程是否被中断的interrupt方法。每个线程都有一个代表其中断状态的布尔属性;中断线程会设置此状态。
中断是一种合作机制。一个线程不能强迫另一个线程停止它正在做的事情并做其他事情;当线程 A 中断线程 B 时,A 只是请求 B 在到达方便的停止点时停止它正在做的事情(如果感觉合适)。虽然 API 或语言规范中没有任何内容要求任何特定的应用程序级别语义中断,中断最明智的用法是取消活动。响应中断的阻塞方法可以更轻松地及时取消长时间运行的活动。
Exceptions and System.exit(int)
异常和 System.exit(int)
The Javadoc of System.exit(int)
says:
Terminates the currently running Java Virtual Machine.The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.
终止当前运行的 Java 虚拟机。参数用作状态码;按照惯例,非零状态代码表示异常终止。
So calling exit()
will (almost) definitely stop your program. In contrast to throwing a RuntimeException
(or an Error
), this can not be caught somewhere down the call stack and it does also not depend on whether there are other threads running. On the other hand, an uncaught exception terminates the thread in which it was thrown, but if there are any other (non-daemon) threads, the program will continue to run.
所以调用exit()
会(几乎)肯定会停止你的程序。与抛出 a RuntimeException
(或 an Error
)相反,这不能在调用堆栈的某处被捕获,并且也不取决于是否有其他线程正在运行。另一方面,未捕获的异常会终止抛出异常的线程,但如果有任何其他(非守护进程)线程,程序将继续运行。
Another difference to throwing an Exception is that exit()
will not print anything to the console (as does an uncaught exception) but instead makes the program return a specific status code. Status codes are sometimes used in shell or batch scripts but other than that, they are not very useful.
抛出异常的另一个区别是它exit()
不会向控制台打印任何内容(就像未捕获的异常一样),而是使程序返回特定的状态代码。状态代码有时用于 shell 或批处理脚本,但除此之外,它们不是很有用。
Runtime.halt(int)
运行时.halt(int)
Finally (for completeness' sake), I'd like to point out a third possibility to exit a Java program. When System.exit(int)
is called (or the program ends in some other way), the runtime does some cleanup work before the Java Virtual Machine is halted. This is described in the Javadoc of Runtime.exit(int)(which is called by System.exit(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.
虚拟机的关闭顺序包括两个阶段。在第一阶段,所有已注册的关闭挂钩(如果有)都以某种未指定的顺序启动,并允许并发运行直到它们完成。在第二阶段,如果启用了退出时终结,所有未调用的终结器都会运行。完成此操作后,虚拟机将停止。
If any shutdown hook or finalizer is prevented from completing, for example because of a deadlock, the program might never actually exit. The only method that guarantees that the JVM halts is Runtime.halt(int):
如果任何关闭挂钩或终结器无法完成,例如由于死锁,程序可能永远不会真正退出。保证 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.
这种方法应该非常谨慎地使用。与 exit 方法不同,如果启用了退出时终结,则此方法不会导致关闭挂钩启动,并且不会运行未调用的终结器。
回答by SJuan76
If there are other (non-daemon) threads running, the JVM won't exit if you stop the main thread. System.exit() kills all the other threads.
如果有其他(非守护进程)线程在运行,如果您停止主线程,JVM 将不会退出。System.exit() 杀死所有其他线程。
回答by Rohit Jain
In a multithreaded application, there are more than one thread executing . Thread.currentThread().interrupt()
only interrupts your current executing thread, but the remaining thread will be running, even if your main thread is interrupted..
在多线程应用程序中,有多个线程在执行。Thread.currentThread().interrupt()
只会中断您当前正在执行的线程,但即使您的主线程被中断,剩余的线程也会运行。
Whereas, System.exit(0)
results your system to be ended.. And all the threads are killed..
然而,System.exit(0)
结果您的系统将结束..并且所有线程都被杀死..