我希望我的线程处理中断,但是由于它是一个检查的异常,所以我无法捕获InterruptedException

问题描述 投票:3回答:4

我有一个Java线程,它调用

t.interrupt();

使t(一个不同的线程)被中断。我希望“ t”线程能够捕获到InterruptedException,但是Eclipse不允许我将InterruptedException声明为未将其放入try主体中。如何获得InterruptedException的呼叫?我使用t.interrupt()错误吗?

java multithreading interrupt
4个回答
7
投票

虽然其他答案正确,但更充分的解释是适当的。

线程只能在其执行的特定点安全地中断(从一般意义上来说)。特别是,它可以在发出wait()调用或调用可以发出wait()的服务时安全地中断。这就是InterruptedException是已检查的异常,而不是运行时(未检查)异常的原因。允许在任何时候任意中断线程将使执行不确定(至少是指定JVM的方式)。强烈建议不要使用Thread#stop()方法,因为它引起的问题多于解决的方法。来自Javadoc

此方法本质上是不安全的。使用Thread.stop停止线程会导致它解锁所有已锁定的监视器(由于未经检查的ThreadDeath异常会在堆栈中传播,这是自然的结果)。如果先前由这些监视器保护的任何对象处于不一致状态,则损坏的对象将对其他线程可见,从而可能导致任意行为。 stop的许多用法应由仅修改某些变量以指示目标线程应停止运行的代码代替。目标线程应定期检查此变量,如果该变量指示要停止运行,则应按有序方式从其运行方法返回。如果目标线程等待很长时间(例如,在条件变量上),则应使用中断方法来中断等待。有关更多信息,请参见Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

如果需要中断正在运行的线程,则必须定期使用Thread.interrupted().isInterrupted()轮询中断状态或轮询共享变量,然后自己采取适当的措施。

注:上面的术语“中断”(作为方法名的一部分除外)是一般意义上的,而不是调用Thread#interrupt()的特定含义。


8
投票

我真的不喜欢这个被接受的答案,所以我想我会把0.02美元投入其中。

我希望“ t”线程随后捕获InterruptedException,但是Eclipse不允许我将InterruptedException声明为未将其插入try主体。我如何才能调用InterruptedException?我使用t.interrupt()错误吗?

重要的是,认识到t.interrupt()仅设置线程中的中断位-实际上,它实际上不是interrupt线程本身的处理。可以在any时间安全地中断线程。

引用Thread.interrupt() javadocs

  • 如果调用Object类的wait(),wait(long)或wait(long,int)方法或join(),join(long),join( long,int),sleep(long)或sleep(long,int)此类的方法,则其中断状态将被清除,并将收到InterruptedException。]]

  • 如果此线程在可中断的通道上被I / O操作阻塞,则该通道将关闭,该线程的中断状态将被设置,并且该线程将收到java.nio.channels.ClosedByInterruptException。

  • 如果此线程在java.nio.channels.Selector中被阻止,则将设置线程的中断状态,并且它将立即从选择操作中返回,可能具有非零值,就像选择器的唤醒方法被调用。

  • 如果以上条件均不成立,则将设置该线程的中断状态。

重要的是,如果已设置线程的中断位并然后

Thread.interrupt()(及其他)被调用,则wait()将立即抛出wait()

所以您无法随处捕获InterruptedException,因为只有某些方法会抛出它。如果要查看线程是否已被中断(再次设置了中断位),则正确的方法是直接使用InterruptedExeption测试该线程。通常,我们会执行以下操作:

Thread.getCurrentThread().isInterrupted()

关于此主题有很多很好的问题和答案:

  • while (!Thread.getCurrentThread().isInterrupted()) { // process stuff ... try { // here's an example of a method that throws InterruptedException Thread.sleep(100); } catch (InterruptedException e) { // catching InterruptedException actually clears the interrupt bit // so it is a good pattern to re-interrupt the thread immediately Thread.currentThread().interrupt(); // now we decide what to do since we are interrupted break; } }
  • What does java.lang.Thread.interrupt() do?
  • How exactly does Thread.interrupt() and Thread.interrupted() work?

3
投票

而不是捕获How to stop uninterruptible threads in Java,您可以调用InterruptedExceptionThread.interrupted()(前者将清除中断标志,后者不会),如果设置了中断标志,则返回true。仅当您调用了抛出该错误的方法时才能捕获它,例如Thread.getCurrentThread().isInterrupted()


2
投票

InterruptedException仅从特定的方法调用中抛出-大多数是等待,睡眠或执行I / O的方法调用,因此不会在任何地方抛出。

© www.soinside.com 2019 - 2024. All rights reserved.