在Java程序的主线程中调用System.exit(0)和Thread.currentThread()。interrupt()有什么区别? [英] What are the differences between calling System.exit(0) and Thread.currentThread().interrupt() in the main thread of a Java program?

查看:338
本文介绍了在Java程序的主线程中调用System.exit(0)和Thread.currentThread()。interrupt()有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两者都会导致程序停止执行。但很明显,这种情况必然存在一些差异。它们是什么?

解决方案

摘要




  1. thread.interrupt()不会停止线程。它用于多线程程序中的协调。除非你确切知道你做了什么,否则不要使用它。

  2. 抛出 RuntimeException 将(通常)终止线程但不一定该程序。

  3. System.exit(int) 几乎总是终止程序并返回状态代码。

  4. 在异常情况下, System.exit(int)可能实际上不会停止程序。 Runtime.getRuntime()。halt(int)另一方面,总是如此。



线程中断



我担心你的第一句话是错的。 Thread.currentThread()。interrupt()不会停止线程或程序。



中断线程是一种表示它停止的方式,但这是一项合作努力:线程中的代码应该不时检查中断状态(在大多数情况下 - 但即使这只是如果被中断,应该停止。如果不这样做,就不会发生任何事情。



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



以下是 Java Concurrency in Practice Brian Goetz的书:


Thread提供中断方法,用于中断
线程并查询线程是否为
打断了。每个线程都有一个布尔属性,
表示其中断状态;中断线程会将
设置为此状态。



中断是一种合作机制。一个线程不能
强制另一个线程来阻止它正在做什么并做一些
else;当线程A中断线程B时,A只是
请求B当它到达
方便的停止点时停止它正在做什么,如果感觉就好了。虽然
中没有任何内容API或语言规范要求
中断的任何特定应用程序级别语义,
最明智的中断用途是取消活动。
阻止响应中断的方法使得
更容易及时取消长期运行的活动。




异常和System.exit(int)



Javadoc System.exit(int) 说:


终止当前运行的Java虚拟机。该参数用作状态代码;按照惯例,非零状态代码表示异常终止。


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



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



Runtime.halt(int)



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


虚拟机的关闭序列包含两个阶段。在第一阶段,所有已注册的关闭挂钩(如果有)都以某种未指定的顺序启动,并允许它们同时运行直到它们完成。在第二阶段所有未被发送的如果已启用finalization-on-exit,则运行终结器。一旦完成此操作,虚拟机将停止。


如果有任何关闭挂钩或如果因为死锁而无法完成终结器,则该程序可能永远不会实际退出。唯一保证JVM停止的方法是 Runtime.halt(int)


此方法应谨慎使用。与exit方法不同,此方法不会导致启动关闭挂钩,并且如果已启用finalization-on-exit,则不会运行未读取的终结器。



Both cause a program to stop executing. It's clear that there must be some differences in how this happens, though. What are they?

解决方案

Summary

  1. 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.
  2. Throwing a RuntimeException will (usually) terminate the thread but not necessarily the program.
  3. System.exit(int) almost always terminates the program and returns a status code.
  4. In unusual situations, System.exit(int) might not actually stop the program. Runtime.getRuntime().halt(int) on the other hand, always does.

Thread Interruption

I'm afraid your first sentence is wrong. Thread.currentThread().interrupt() does not stop the thread or the program.

Interrupting a thread is a way to signal that it should stop, 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 interrupted flag. 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.

Here are the relevant parts from the Java Concurrency in Practice book by Brian Goetz:

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.

Exceptions and 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.

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.

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.

Runtime.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):

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):

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程序的主线程中调用System.exit(0)和Thread.currentThread()。interrupt()有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆