问题描述
我已经阅读并重新阅读 Java Concurrency in Practice,我已经阅读了关于这个主题的几个主题,我已经阅读了 IBM 文章 处理 InterruptedException 但有些事情我根本没有掌握,我认为可以分为两个问题:
I've read and re-read Java Concurrency in Practice, I've read several threads here on the subject, I've read the IBM article Dealing with InterruptedException and yet there's something I'm simply not grasping which I think can be broken down into two questions:
如果我自己从不中断其他线程,那么什么会触发 InterruptedException?
如果我自己从来没有使用 interrupt() 中断其他线程(比如说因为我正在使用其他方式来取消我的工作线程,例如毒丸和 while(!cancelled) 样式循环 [正如 JCIP 中所解释的]),那么 InterruptedException 是什么意思?抓到一只我该怎么办?关闭我的应用程序?
If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
推荐答案
线程中断机制是让(合作的)线程响应请求以停止正在执行的操作的首选方式.任何线程(包括我认为的线程本身)都可以在线程上调用 interrupt()
.
The Thread interrupt mechanism is the preferred way to get a (cooperating) thread to respond a request to stop what it is doing. Any thread (including the thread itself I think) could call interrupt()
on a Thread.
在实践中,interrupt()
的正常用例涉及某种框架或管理器告诉某个工作线程停止他们正在做的事情.如果工作线程是中断感知"的,它将注意到它已通过异常或定期检查其中断标志而被中断.当注意到它被中断时,一个表现良好的线程会放弃它正在做的事情并结束自己.
In practice, the normal use-cases for interrupt()
involve some kind of framework or manager telling some worker thread to stop what they are doing. If the worker thread is "interrupt aware" it will notice that it has been interrupted via an exception, or by periodically checking its interrupted flag. On noticing that it has been interrupted, a well-behaved thread would abandon what it is doing and end itself.
假设上述用例,如果您的代码在 Java 框架内或从某个工作线程中运行,它可能会被中断.当它被中断时,你的代码应该放弃它正在做的事情并以最合适的方式结束它.根据调用代码的方式,这可以通过返回或抛出一些适当的异常来完成.但它可能不应该调用 System.exit()
.(你的应用不一定知道为什么被中断,当然也不知道是否还有其他线程需要被框架中断.)
Assuming the above use-case, your code is likely to be interrupted if it is run within a Java framework or from some worker thread. And when it is interrupted, your code should abandon what it is doing and cause itself to end by the most appropriate means. Depending on how your code was called, this might be done by returning or by throwing some appropriate exception. But it probably should not call System.exit()
. (Your application does not necessarily know why it was interrupted, and it certainly does not know if there are other threads that need to be interrupted by the framework.)
另一方面,如果您的代码并非设计为在某些框架的控制下运行,您可能会认为 InterruptedException
是一个意外异常;即一个错误.在这种情况下,您应该像对待其他错误一样对待异常;例如将其包装在未经检查的异常中,并在处理其他意外未经检查的异常的同时捕获并记录它.(或者,您的应用程序可以简单地忽略中断并继续执行它正在执行的操作.)
On the other hand, if your code is not designed to run under the control of some framework, you could argue that the InterruptedException
is an unexpected exception; i.e. a bug. In that case, you should treat the exception as you would other bugs; e.g. wrap it in an unchecked exception, and catch and log it at the same point you deal with other unexpected unchecked exceptions. (Alternatively, your application could simply ignore the interrupt and continue doing what it was doing.)
1) 如果我自己从不中断其他线程,什么会触发 InterruptedException?
1) If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
一个例子是,如果您的 Runnable
对象使用 ExecutorService
执行,并且在服务上调用 shutdownNow()
.理论上,任何第 3 方线程池或线程管理框架都可以合法地做这样的事情.
One example is if your Runnable
objects are executed using an ExecutorService
and shutdownNow()
is called on the service. And in theory, any 3rd-party thread pool or thread management framework could legitimately do something like this.
2) 如果我自己从来没有使用 interrupt() 中断过其他线程……那么 InterruptedException
是什么意思?抓到一只我该怎么办?关闭我的应用?
2) If I'm never ever interrupting other threads myself using interrupt() ... what does an
InterruptedException
then mean? What am I supposed to do upon catching one? Shutdown my app?
您需要分析代码库以找出导致 interrupt()
调用的原因以及原因.一旦你弄清楚了,你就可以计算出 >>your<<部分应用需要做的事情.
You need analyze the codebase to figure out what is making the interrupt()
calls and why. Once you have figured that out, you can work out what >>your<< part of the app needs to do.
在您知道为什么抛出 InterruptedException
之前,我建议将其视为硬错误;例如将堆栈跟踪打印到日志文件并关闭应用程序.(显然,这并不总是正确的答案......但关键是这是一个错误",需要引起开发人员/维护人员的注意.)
Until you know why InterruptedException
is being thrown, I would advise treating it as a hard error; e.g. print a stacktrace to the log file and shut down the app. (Obviously, that's not always the right answer ... but the point is that this is "a bug", and it needs to be brought to the attention of the developer / maintainer.)
3) 我如何找出谁/什么在调用interrupt()
?
3) How do I find out who / what is calling
interrupt()
?
对此没有好的答案.我能建议的最好方法是在 Thread.interrupt()
上设置一个断点并查看调用堆栈.
There is no good answer to this. The best I can suggest is to set a breakpoint on the Thread.interrupt()
and look at the call stack.
这篇关于如果我不是,谁在调用 Java 线程的 interrupt() 方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!