java 如果没有人调用interrupt(),可以忽略InterruptedException吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28544867/
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
Is it OK to ignore InterruptedException if nobody calls interrupt()?
提问by Hilikus
If I create my own thread (i.e. not a threadpool) and somewhere I call sleep
or any other interruptible method, is it ok to ignore the InterruptedException if I know nobody else in the code is doing an interrupt on the thread.
如果我创建了自己的线程(即不是线程池)和我调用的某个地方sleep
或任何其他可中断的方法,如果我知道代码中没有其他人在线程上执行中断,是否可以忽略 InterruptedException 。
In other words, if the thread is supposed to live as long as the JVM, meaning the thread is not interruptible, is it safe to assume that InterruptedException will neverbe called and therefore the exception can be swallowed?
换句话说,如果线程应该与 JVM 一样长,这意味着线程不可中断,那么假设 InterruptedException永远不会被调用并因此可以吞下异常是否安全?
采纳答案by Zhedar
Ignoring a checked exception is never considered to be safe.
It may be ok for you at the moment, but if another programmer extends your code, he will expect the standard behaviour: the thread reacting to an interrupt call.
Also an empty catch block is dangerous in this case, since the JVM removes the interrupted flag and it should definitely be set again with
忽略已检查的异常永远不会被认为是安全的。
目前对您来说可能没问题,但是如果另一个程序员扩展了您的代码,他会期望标准行为:线程对中断调用做出反应。
在这种情况下,空的 catch 块也是危险的,因为 JVM 删除了中断标志,并且绝对应该再次设置它
Thread.currentThread().interrupt();
in the catch block. In my opinion, this is the minimum catch implementation for InterruptedException
s. Checking for the isInterrupted
flag in a loop doesn't hurt much, either.
It is little overhead compared to your future programmer self's hassle searching a day or two for unexpected thread behaviour as you project may have grown a bit.
在 catch 块中。在我看来,这是InterruptedException
s的最小捕获实现。isInterrupted
在循环中检查标志也不会造成太大伤害。
与您未来的程序员自己在您的项目可能有所增长时为意外的线程行为搜索一两天的麻烦相比,它的开销很小。
If you feel that your code's readability suffers from those catch implementations, you may implement your own safeSleep
utility method, which takes care of the Exception
s and sets the flag properly.
如果你觉得你的代码的可读性受到那些 catch 实现的影响,你可以实现你自己的safeSleep
实用方法,它负责Exception
s 并正确设置标志。
On the other hand, InterruptedException
is not thrown by the JVM itself in case of a hardware failure, it is a user indicated Exception
only. So, if you do not propagate your That's it technically. But you shouldn't underestimate the human factor and your programs evolution.Thread
s reference, there won't be any other Thread
s that are able to call Thread.interrupt()
on it.
Edit:As ruakhpointed out, there actually is a way to get a Thread
s reference and thus to schedule an Thread.interrupt()
call. That way the developer in heat may not even have to look at the class, that implements your uninterruptible Thread
. In my opinion that's even another reason, to implement proper exception handling.
Another thing: If you're not throwing an Exception
, logging such an event on a level beyond INFO
may be a good choice.
在另一方面,InterruptedException
不是由JVM本身在硬件故障的情况下抛出,这是指示的用户Exception
只。因此,如果您不传播您的技术上就是这样。但是您不应该低估人为因素和您的程序演变。Thread
s 引用,则不会有任何其他Thread
s 能够调用Thread.interrupt()
它。
编辑:正如ruakh 所指出的,实际上有一种方法可以获取Thread
s 引用,从而安排Thread.interrupt()
通话。这样,热身的开发人员甚至可能不必查看实现您的不间断的类Thread
. 在我看来,这甚至是另一个原因,即实施适当的异常处理。
另一件事:如果您不抛出Exception
,那么在超出级别记录此类事件INFO
可能是一个不错的选择。
回答by Dan Getz
Instead of swallowing it, if you're so sure it will never happen, you can crash instead of ignoring it. For example, throw an Error
(or a RuntimeException
):
与其吞下它,如果您确信它永远不会发生,您可以崩溃而不是忽略它。例如,抛出一个Error
(或一个RuntimeException
):
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new Error(e);
}
From the Javadocs for Error:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.
Error 是 Throwable 的一个子类,它指示合理的应用程序不应尝试捕获的严重问题。大多数此类错误是异常情况。
If you think it's worth assuming something will never happen, then if it does happen, that's an "abnormal condition" that, who knows, might just be a "serious problem".
如果你认为值得假设某事永远不会发生,那么如果它确实发生了,那是一种“异常情况”,谁知道,可能只是一个“严重问题”。
Another way to look at this is, if someone in the future doesinterrupt your method, is there any chance that they will want it to continue running as if nothing had happened? I would guess no.
看待这一点的另一种方式是,如果将来有人确实中断了您的方法,他们是否有可能希望它继续运行,就好像什么也没发生过一样?我猜不会。
回答by Holger
You should never swallow an exception if you think that it should never occur. It's ok to decide not to add code handling a condition which never occurs but it shouldn't happen silently.
如果您认为它不应该发生,则永远不应该吞下异常。可以决定不添加处理从未发生但不应该静默发生的条件的代码。
The minimum you should do is:
你应该做的最低限度是:
catch(InterruptedException ex) {
throw new AssertionError(ex);
}
This ensures that whenever your assertion that this will never occur is wrong, you will notice. This pattern also applies to other unexpected exceptions, e.g. IOException
when you know that the target OutputStream
is a ByteArrayOutputStream
or the Appendable
of a Formatter
ought to be a StringBuilder
, etc.
这可确保无论何时您断言这永远不会发生是错误的,您都会注意到。此模式也适用于其他意外异常,例如,IOException
当您知道目标OutputStream
是 aByteArrayOutputStream
或Appendable
a 的 aFormatter
应该是 aStringBuilder
等时。
By the way, there is an alternative to Thread.sleep
not requiring to deal with InterruptedException
at all:
顺便说一句,有一个替代方案可以Thread.sleep
完全不需要处理InterruptedException
:
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(timeInMillis));
This method will simply return earlier when the thread has been interrupted and retain the interrupted state of the Thread
so it provides already a correct handling for the case that your code is used by someone else who doesuse interruption (assuming that the caller of your code checks the interrupted state then).
这种方法只会更早返回时,线程已经中断和保留的中断状态,Thread
所以它已经提供了的情况下,正确处理你的代码由别人谁不使用中断(假设你的代码检查的调用者中断状态)。
回答by Fizz
The book that I still consider the bible on these matters, Goetz et al. Java Concurrency in Practicesays the following important bits in chapter 7 (Pretty much the same material is found in Goetz's developerWorks article, which has the advantage of being free, but the book is a bit more clear on some points.)
这本书我仍然认为圣经关于这些问题,Goetz 等人。Java Concurrency in Practice在第 7 章中说了以下重要内容(Goetz 的developerWorks 文章 中的材料几乎相同,该文章的优点是免费,但本书在某些方面更清楚一些。)
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.
[...]
Only code that implements a thread's interruption policy may swallow an interruption request. General-purpose task and library code should never swallow interruption requests.
中断是一种合作机制。一个线程不能强迫另一个线程停止它正在做的事情并做其他事情;当线程 A 中断线程 B 时,A 只是请求 B 在到达一个方便的停止点时停止它正在做的事情——如果它感觉像的话。
[...]
只有实现线程中断策略的代码才能吞下中断请求。通用任务和库代码永远不应该吞下中断请求。
So, yes, you can "swallow" InterruptedException
under the circumstances you outlined.
所以,是的,您可以InterruptedException
在您概述的情况下“吞下” 。
Also an important point in the book:
书中还有一个重要的观点:
Because each thread has its own interruption policy, you should not interrupt a thread unless you know what interruption means to that thread.
因为每个线程都有自己的中断策略,除非您知道中断对该线程意味着什么,否则不应中断该线程。
So you can choose your own policy like "crashing" with a RuntimeException
, AssertionError
, just logging it as a warning, or ignoring interruption altogether as long as you document this issue for whoever else might need to know. What is best depends on what your thread is really doing and you haven't provided any details on that. For example, if it's running on a rocket [say doing attitude control], you do not want to crash the JVM/rocket just because a fellow programmer [who might not even work for the same company as you, e.g. he wrote some library you call] forgot about a certain contract somewhere in his code and dumps a safely ignorable exception on yours: "The exception which occurred was not due to random failure but a design error."
所以,你可以选择像“崩溃”了自己的政策RuntimeException
,AssertionError
,只是记录它作为一个警告,或者只要共你记录这个问题对于不管是谁可能需要知道忽略中断。什么是最好的取决于您的线程真正在做什么,而您尚未提供任何详细信息。例如,如果它在火箭上运行 [比如说做姿态控制],你不想仅仅因为一个程序员同事 [他甚至可能和你不在同一家公司工作,例如他写了一些你call] 在他的代码中某处忘记了某个合同,并在您的代码中转储了一个安全可忽略的异常:“发生的异常不是由于随机故障,而是由于设计错误。”
回答by Jan
If your Projekt grows and gets more complex, it's getting harder to say that definitely no one would call the interrupt method. If someone would call this method some day and an InterruptedException occurs it's getting really hard to debug this if you're not at least logging it somewhere.
如果您的 Projekt 增长并变得更加复杂,则很难说绝对没有人会调用中断方法。如果有一天有人会调用此方法并且发生 InterruptedException,那么如果您不至少在某处记录它,那么调试它会变得非常困难。
回答by M Anouti
It should not be ignored. It should either be thrown back to the caller or you should reassert the thread's interrupted status which is cleared when the exception is thrown:
它不应该被忽视。它应该被抛出回调用者,或者你应该重新声明线程的中断状态,当抛出异常时该状态被清除:
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
unless you prompty exit the thread after the catch.
除非您在捕获后立即退出线程。
Here's an article about dealing with InterruptedException
s.
这是一篇关于处理 s 的文章InterruptedException
。
回答by Marko Topolnik
if the thread is supposed to live as long as the JVM, meaning the thread is not interruptible, is it safe to assume that
InterruptedException
will neverbe thrown and therefore the exception can be swallowed?
如果线程应该只要住的JVM,这意味着线程没有中断,是安全的假设,
InterruptedException
将永远不会被抛出,因此异常可以被吞噬?
I understand your pain, the proliferation of boilerplate try-catch blocks with no business value hurts the code.
我理解您的痛苦,没有商业价值的样板 try-catch 块的激增会损害代码。
If the code where you intend to swallow the exception is entirely under your control, and if it is just client code(it will never be reused in context other than your own), then it is safe to swallow the exception. Note that there are a lot of ifs there.
如果您打算吞下异常的代码完全在您的控制之下,并且如果它只是客户端代码(它将永远不会在您自己的上下文中重用),那么吞下异常是安全的。请注意,那里有很多if。
If you happen to work with Java 8, you have another option, described here: wrap your code inside an uncheckCall(() -> { ... })
block. This lets the code block throw the InterruptedException
without declaring it. As explained in the linked answer, this should be handled with extreme care, but it has the potential of making your code quite clean.
如果您碰巧使用 Java 8,您还有另一种选择,此处描述:将代码包装在一个uncheckCall(() -> { ... })
块中。这让代码块在InterruptedException
不声明的情况下抛出。正如链接的答案中所解释的,这应该非常小心地处理,但它有可能使您的代码非常干净。
回答by Mak
I think, ignoring InterruptedException is safe or not, depends upon what you are doing in that thread. If there is any scenario when an unwanted interrupt to your thread can leave System or any resource in unwanted state (dirty, locked, not released which can cause leaking resource) then its your responsibility to handle the InterruptedException and you should not ignore it. It's up to you whether you want your to make your thread Interruptible or not.
我认为,忽略 InterruptedException 是否安全,取决于您在该线程中做什么。如果在任何情况下,线程的不需要的中断会使系统或任何资源处于不需要的状态(脏、锁定、未释放,这可能导致资源泄漏),那么您有责任处理 InterruptedException 并且不应忽略它。您是否希望您的线程可中断取决于您。
In other words Interrupt mechanism is mainly used for implementing the cancellation policies and task clean up. Is you don't have anything to clean in task or you dont have any specific task cancellation policies, ignoring IntrruptedException may not sound politically correct but is OK.
换句话说,中断机制主要用于实现取消策略和任务清理。如果您在任务中没有任何要清理的东西,或者您没有任何特定的任务取消政策,忽略 IntrruptedException 可能在上不正确但没关系。