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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:42:26  来源:igfitidea点击:

Java: Difference in usage between Thread.interrupted() and Thread.isInterrupted()?

javamultithreading

提问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 staticand checks the current thread. isInterrupted()is an instance method which checks the Threadobject 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 falseeven 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,您要问的是“自从我上次问起后,我是否被打断过?”

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

以下是一些有关如何使用这些方法的示例:

  1. 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.

  2. 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 of Thread.interrupted()to check on the status of your current thread.

  1. 如果您正在编写自己的线程池,您可能需要检查您正在管理的线程之一的中断状态。在这种情况下,你会打电话managedThread.isInterrupted()来检查它的中断状态。

  2. 如果您正在编写自己的 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 InterruptedExceptiondue 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.interrupton your thread, during the current or next twiddlecall an InterruptedExceptionwill be thrown up and stop your task.

那么你不需要做任何其他事情;如果有人调用Thread.interrupt您的线程,在当前或下一次twiddle调用期间,InterruptedException将抛出并停止您的任务。

But what if twiddledoes notthrow InterruptedExceptionand generally cannot be interrupted in the middle? Say each such call takes 100ms, but things.lengthmight be 100. Then processcould 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:

但是,如果twiddleInterruptedException,一般不能在中途被打断?假设每个这样的调用需要 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 interruptedatomically 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 processis assuming it ran to completion, simply returning as shown here would be misleading. So you might want to make processreturn 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.

在这里,我们可以更快地处理剩余的事情,但仍然完成循环,并重新打开中断标志,以便我们的调用者可以决定处理它。