简体   繁体   English

关于Thread.interrupted()的Java困惑

[英]java confusion about Thread.interrupted()

I was going through oracle java tutorial about threads and I saw this example 我正在阅读有关线程的oracle java教程,并且看到了此示例

src: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html src: http//docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

What if a thread goes a long time without invoking a method that throws InterruptedException? 如果线程长时间运行而没有调用引发InterruptedException的方法怎么办? Then it must periodically invoke Thread.interrupted, which returns true if an interrupt has been received. 然后,它必须定期调用Thread.interrupted,如果收到中断,则返回true。 For example: 例如:

for (int i = 0; i < inputs.length; i++) {
      heavyCrunch(inputs[i]);
      if (Thread.interrupted()) {
           // We've been interrupted: no more crunching.
      return;
}

The tutorial adds : The interrupt mechanism is implemented using an internal flag known as the interrupt status. 该教程补充说: 中断机制是使用内部标志(称为中断状态)实现的。 Invoking Thread.interrupt sets this flag. 调用Thread.interrupt设置此标志。 When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. 当线程通过调用静态方法Thread.interrupted检查中断时,将清除中断状态。 The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag. 一个线程用于查询另一线程的中断状态的非静态isInterrupted方法不会更改中断状态标志。

By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. 按照惯例,任何通过抛出InterruptedException退出的方法都会清除中断状态。 However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt. 但是,总是有可能通过另一个调用中断的线程立即再次设置中断状态。

now I'm confused. 现在我很困惑。 When does it happen? 什么时候发生? if there is an interrupt, shouldn't the thread receive an InterruptedException? 如果有中断,线程不应该收到InterruptedException吗?

When someone might use these method of checking in their code? 何时有人可以使用这些方法来检查代码? The Thread.interrupt (the flag) is static, so with the above check, we actually check if any of the treads has been interrupted? Thread.interrupt(标志)是静态的,因此通过以上检查,我们实际上检查是否有任何胎面已被中断? even if that is the case, according to the tutorial, When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. 即使是这种情况,根据本教程, 当线程通过调用静态方法Thread.interrupted检查中断时,也会清除中断状态。 or any method that exits by throwing an InterruptedException clears interrupt status when it does so 通过抛出InterruptedException退出的任何方法清除中断状态

So, Am I missing something? 所以,我有什么想念的吗? or this is only useful, if some thread has received an interrupt, but doesn't check it, or does not throw it? 或者这仅在某些线程收到中断但不检查或不抛出中断时有用吗?

This is Thread.interrupted implementation 这是Thread.interrupted实现

public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

private native boolean isInterrupted(boolean ClearInterrupted);

as you can see it can check / reset only current thread's interrupted status. 如您所见,它只能检查/重置当前线程的中断状态。 If it were not static you could call it on other threads and reset their status which is not allowed by API. 如果不是静态的,则可以在其他线程上调用它并重置API不允许的状态。

Not all methods, in Thread , throws InterrupedException s. 并非Thread所有方法都抛出InterrupedException It is mostly common at sleeps and waits, or any time consuming methods. 它通常在睡眠和等待时或任何耗时的方法中很常见。 This is the way Java implemented it. 这就是Java实现它的方式。 ( sleep(...) is native code, so I cant show you the source.) sleep(...)native代码,因此我无法向您显示源代码。)

For example: 例如:

try {
    Thread.sleep(1000); // one sec
} catch(InterruptedException e){
}

But you can't force to include a simple for loop, in a try..catch clause. 但是您不能强迫在try..catch子句中包含一个简单的for循环。

If you subclass Thread , you should follow the conventions, posted. 如果您将Thread子类化,则应遵循发布的约定。


For your second question, about the static method, here's the internal code: 关于static方法的第二个问题,这是内部代码:

public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

So you can see, it just sets, an instance in the current thread. 因此,您可以看到它只是在当前线程中设置了一个实例

Many times a Thread is doing a lot of waiting or blocking . 很多时候,一个线程正在做很多等待或阻塞 In almost all of these cases the method that is doing the blocking supports InterruptedException. 在几乎所有这些情况下,进行阻塞的方法都支持InterruptedException。 Some examples: 一些例子:

  1. Thread.sleep(millis); Thread.sleep(millis);
  2. obj = arrayBlockingQueue.take(); obj = arrayBlockingQueue.take();
  3. obj.wait(); obj.wait();

What the referenced article is pointing out is that if your thread is not blocking, meaning there is no method that supports InterruptedException, then it is your responsibility to check if your thread has been interrupted. 被引用的文章指出的是,如果您的线程未阻塞,则意味着没有支持InterruptedException的方法,那么您有责任检查线程是否已被中断。 This is accomplished by testing Thread.interrupted() . 这是通过测试Thread.interrupted()完成的。

The method Thread.interrupt() is in fact not static and is called from another Thread to interrupt that thread. 实际上, Thread.interrupt()方法不是静态的,并且从另一个Thread调用以中断该线程。 See the following: 请参阅以下内容:

Thread.interrupt() Thread.interrupt()

Does that make sense? 那有意义吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM