Java:Thread.interrupted() 和 Thread.isInterrupted() 在用法上的区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1904072/
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
Java: Difference in usage between Thread.interrupted() and Thread.isInterrupted()?
提问by python dude
Java question: As far as I know, there are two ways to check inside a thread whether the thread received an interrupt signal, Thread.interrupted()
and Thread.isInterrupted()
, and the only difference between them is that the former resets the internal interrupted flag.
Java问题:据我所知,在线程内部检查线程是否收到中断信号有两种方法,Thread.interrupted()
和Thread.isInterrupted()
,唯一的区别是前者重置了内部中断标志。
So far, I've always used Thread.isInterrupted()
and never had any problems with it. Then again, most tutorials I've seen recommend using Thread.interrupted()
. Is there any specific reason for that?
到目前为止,我一直在使用它Thread.isInterrupted()
,从来没有遇到过任何问题。再说一次,我见过的大多数教程都推荐使用Thread.interrupted()
. 有什么具体原因吗?
采纳答案by Michael Myers
interrupted()
is static
and checks the current thread. isInterrupted()
is an instance method which checks the Thread
object that it is called on.
interrupted()
isstatic
并检查当前线程。isInterrupted()
是一个实例方法,用于检查Thread
调用它的对象。
A common error is to call a static method on an instance.
一个常见的错误是在实例上调用静态方法。
Thread myThread = ...;
if (myThread.interrupted()) {} // WRONG! This might not be checking myThread.
if (myThread.isInterrupted()) {} // Right!
Another difference is that interrupted()
also clears the status of the current thread. In other words, if you call it twice in a row and the thread is not interrupted between the two calls, the second call will return false
even if the first call returned true
.
另一个区别是interrupted()
同时清除当前线程的状态。换句话说,如果连续调用两次并且两次调用之间线程没有中断,那么false
即使第一次调用返回了,第二次调用也会返回true
。
The Javadocstell you important things like this; use them often!
该Javadoc中告诉你,这样重要的事情; 经常使用它们!
回答by Anon.
If you use interrupted
, what you're asking is "Have I been interrupted since the last time I asked?"
如果您使用interrupted
,您要问的是“自从我上次问起后,我是否被打断过?”
isInterrupted
tells you whether the thread you call it on is currently interrupted.
isInterrupted
告诉您调用它的线程当前是否被中断。
回答by Dean Povey
Thread interruption in Java is advisory. If you call Thread.interrupt() then it will set the flag and cancel any outstanding IO tasks (which will throw InterruptedException). However it is up to code that is executing in the thread to handle this. Doing so is called implementing the Thread interruption policy.
Java 中的线程中断是建议性的。如果您调用 Thread.interrupt() 那么它将设置标志并取消任何未完成的 IO 任务(这将抛出 InterruptedException)。然而,这取决于在线程中执行的代码来处理这个问题。这样做称为实现线程中断策略。
However because Thread's interrupted state is shared it is important that any such handling be Thread Safe. You don't want some other thread going off and trying to do something with the interrupted flag if you are handling it. For this reason the Thread.interrupted() flag makes this atomic so it is used when you want to say: "If this thread was interrupted then I am going to deal with it). Usually this will involve cleaning up some resources. Once you are done you should probably propogate the interrupted flag so that callers can handle it. You can do this by recalling Thread.interrupt.
然而,由于线程的中断状态是共享的,因此任何此类处理都是线程安全的,这一点很重要。如果您正在处理它,您不希望其他一些线程关闭并尝试对中断标志执行某些操作。由于这个原因,Thread.interrupted() 标志使这个原子化,所以当你想说:“如果这个线程被中断,那么我将处理它。通常这将涉及清理一些资源。一旦你完成后,您可能应该传播中断标志,以便调用者可以处理它。您可以通过调用 Thread.interrupt 来做到这一点。
回答by erickson
The interrupted()
method is a class method that alwayschecks the current thread andclears the interruption "flag". In other words, a second call to interrupted()
will return false
.
该interrupted()
方法是一个始终检查当前线程并清除中断“标志”的类方法。换句话说,第二次调用interrupted()
将返回false
。
The isInterrupted()
method is an instance method; it reports the status of the thread on which it is invoked. Also, it does not clear the interruption flag. If the flag is set, it will remain set after calling this method.
该isInterrupted()
方法是一个实例方法;它报告调用它的线程的状态。此外,它不清除中断标志。如果设置了标志,则在调用此方法后它将保持设置状态。
回答by Bob Cross
Here are a couple of examples of how you might use these methods:
以下是一些有关如何使用这些方法的示例:
If you were writing your own thread pool, you might want to check the interrupted status on one of the threads that you are managing. In that case, you would call
managedThread.isInterrupted()
to check it's interrupted status.If you are writing your own InterruptedException handlers that don't immediately retrigger an equivalent exception via
Thread.currentThread().interrupt()
(for example, you might have a finally block after your exception handlers), you might want to check whether that thread that you are currently running on has been interrupted via an outside call or InterruptedException. In that case, you would check the boolean value ofThread.interrupted()
to check on the status of your current thread.
如果您正在编写自己的线程池,您可能需要检查您正在管理的线程之一的中断状态。在这种情况下,你会打电话
managedThread.isInterrupted()
来检查它的中断状态。如果您正在编写自己的 InterruptedException 处理程序,但不会立即通过
Thread.currentThread().interrupt()
(例如,您的异常处理程序之后可能有一个 finally 块)重新触发等效异常,您可能需要检查您当前正在运行的线程是否已通过外部调用或 InterruptedException 中断。在这种情况下,您将检查 的布尔值Thread.interrupted()
以检查当前线程的状态。
The second method is really only ever useful to me in situations where I'm afraid that someone has written an exception eater at a lower level that, by extension, has eaten an InterruptedException as well.
第二种方法真的只在我担心有人在较低级别编写了一个异常食者的情况下对我有用,通过扩展,它也吃了一个 InterruptedException 。
回答by Vijay Bhaskar Semwal
interrupted() method is a static method of class thread checks the current thread and clear the interruption "flag".i.e. a second call to interrupted() will return false.
interrupted() 方法是类线程的静态方法,检查当前线程并清除中断“标志”。即第二次调用interrupted() 将返回false。
isInterrupted() method is an instance method; it reports the status of the thread on which it is invoked. it does not clear the interruption flag.
isInterrupted() 方法是一个实例方法;它报告调用它的线程的状态。它不清除中断标志。
If the flag is set, it will remain set after calling this method.
如果设置了标志,则在调用此方法后它将保持设置状态。
Thread myThread = ...;
if (myThread.interrupted()) {} //error
Thread.interrupted()//right
if (myThread.isInterrupted()) {} // Right
回答by Inquisitive
This is a old question and having gone through the answers I feel that there is still some missing information. Here's my attempt to fill in that missing piece of info.
这是一个老问题,经过答案后,我觉得仍然缺少一些信息。这是我尝试填写缺失的信息。
From Java 5 onwards usually you would deal with Threads only indirectly .Infact threads spawned from the java.util.Executor framework are dealt within library methods. These threads often call entities that are of blocking nature like Future.get()
. ie get()
blocks untill result is available .Now there is a overloaded form of get()
that takes a timeout value and calling that method means that the thread wants to wait for a period equal to the timeout for the get ()
to return a value ,if not that task can be cancelled via Future.cancel(). So these methods deal with interruption seriously in that as soon as they sniff a interruption , they also throw the checked InterruptionException . Hence the callers are forced to handle InterruptionException. Since they already propagate the InterruptedException which conveys the interrupted status , it makes sense for the blocking mehthods to also clear the interrupted status by calling Thread.interrupt(). Otherwise , the contract of InterruptedException is violated.
从 Java 5 开始,您通常只会间接处理线程。事实上,从 java.util.Executor 框架产生的线程是在库方法中处理的。这些线程通常调用具有阻塞性质的实体,例如Future.get()
. 即get()
阻塞直到结果可用。现在有一个重载形式,get()
它需要一个超时值,调用该方法意味着线程想要等待一个等于超时的时间段get ()
以返回一个值,如果没有,该任务可以通过Future.cancel()取消. 因此,这些方法认真对待中断,因为一旦它们嗅到中断,它们也会抛出已检查的 InterruptionException 。因此,调用者被迫处理 InterruptionException。由于它们已经传播了传达中断状态的 InterruptedException,因此阻塞方法也可以通过调用 Thread.interrupt() 来清除中断状态。否则,违反了 InterruptedException 的约定。
However , if you are dealing with raw threads which is ofcourse not recommnended now , you should be careful when calling the static method interrupted()
because if you call it twice in a row and the thread is not interrupted between the two calls, the second call will return false even if the first call returned true.
但是,如果您正在处理现在当然不推荐的原始线程,则在调用静态方法时应该小心,interrupted()
因为如果连续调用它两次并且线程在两次调用之间没有中断,则第二次调用将返回即使第一次调用返回 true,也为 false。
回答by Jesse Glick
There are a lot of idioms surrounding InterruptedException
, but the question was about checking the interrupted status explicitly.
周围有很多习语InterruptedException
,但问题是关于明确检查中断状态。
My understanding is that isInterrupted
(the instance method) should rarely be used—mainly for logging and debugging and the like. It only gives a snapshot of the flag on a given thread, which can be outdated soon afterwards.
我的理解是isInterrupted
(实例方法)应该很少使用——主要用于日志记录和调试等。它只提供给定线程上标志的快照,此后很快就会过时。
The normal idiom is to check interrupted
(the static method) if you are writing a task which you want to be cancelable at a certain point where it is notcalling something that throws InterruptedException
due to a sleep or blocking I/O call or the like. If you see the flag set, you should stop your current computation as quickly as you can, returning early or throwing an exception (perhaps InterruptedException
).
正常的习惯用法是检查interrupted
(静态方法)您是否正在编写一个您希望在某个点取消的任务,该任务不调用InterruptedException
由于睡眠或阻塞 I/O 调用等而引发的某些内容。如果您看到设置了标志,您应该尽快停止当前的计算,提前返回或抛出异常(可能InterruptedException
)。
So as an example, if your task looks something like
举个例子,如果你的任务看起来像
void process(Things[] things) throws InterruptedException {
for (Thing thing : things) {
thing.twiddle(); // this call throws InterruptedException
}
}
then you do not need to do anything else; if someone calls Thread.interrupt
on your thread, during the current or next twiddle
call an InterruptedException
will be thrown up and stop your task.
那么你不需要做任何其他事情;如果有人调用Thread.interrupt
您的线程,在当前或下一次twiddle
调用期间,InterruptedException
将抛出并停止您的任务。
But what if twiddle
does notthrow InterruptedException
and generally cannot be interrupted in the middle? Say each such call takes 100ms, but things.length
might be 100. Then process
could be blocked for 10s even if someone is trying to interrupt it, which may be unacceptable in your application. So you can explicitly check for interrupts:
但是,如果twiddle
不不扔InterruptedException
,一般不能在中途被打断?假设每个这样的调用需要 100 毫秒,但things.length
可能是 100毫秒。然后process
即使有人试图中断它也可能被阻止 10 秒,这在您的应用程序中可能是不可接受的。因此,您可以明确检查中断:
void process(Things[] things) {
if (Thread.interrupted()) {
return;
}
for (Thing thing : things) {
thing.twiddle();
}
}
Here you can see why it is important that interrupted
atomically checks and clears the flag: you are using it to acknowledge receipt of a message, that someone has politely requested you stop as soon as possible. (In this case, within about 100ms of the request.) You can also see why this must be a static method, operating on the current thread: it only makes sense in the context of checking whether the surrounding code should be stopped.
在这里,您可以看到为什么以interrupted
原子方式检查和清除标志很重要:您正在使用它来确认收到一条消息,有人礼貌地要求您尽快停止。(在这种情况下,在请求的大约 100 毫秒内。)您还可以看到为什么这必须是一个静态方法,在当前线程上运行:它仅在检查是否应该停止周围代码的上下文中才有意义。
Of course if the caller of process
is assuming it ran to completion, simply return
ing as shown here would be misleading. So you might want to make process
return the number of things it finished processing, or it might just be more appropriate to throw the exception up:
当然,如果 的调用者process
假设它运行完成,那么简单地return
按照此处所示进行 ing 会产生误导。所以你可能想要process
返回它完成处理的数量,或者抛出异常可能更合适:
void process(Things[] things) throws InterruptedException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
for (Thing thing : things) {
thing.twiddle();
}
}
In this case the caller gets a (checked) exception informing them that someone else asked to stop processing in the middle. Usually the caller should just let the exception be thrown up the call stack.
在这种情况下,调用者会收到一个(已检查的)异常,通知他们其他人要求在中间停止处理。通常调用者应该让异常被抛出调用堆栈。
You could also reinterrupt yourself if you were unable to stop your current task yet needed to know that a request to stop it did come in, for example to cut the rest of the work short:
如果您无法停止当前任务但需要知道停止它的请求确实出现了,您也可以重新中断自己,例如缩短其余工作:
void process(Things[] things) {
boolean twiddleFully = true;
if (twiddleFully && Thread.interrupted()) {
twiddleFully = false;
Thread.currentThread().interrupt();
}
for (Thing thing : things) {
thing.twiddle(twiddleFully);
}
}
Here we can process the remaining things more quickly but still complete the loop, and turn the interrupted flag back on so that our caller can decide to handle it.
在这里,我们可以更快地处理剩余的事情,但仍然完成循环,并重新打开中断标志,以便我们的调用者可以决定处理它。