Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我希望我的线程能够处理中断,但我可以';t捕获InterruptedException,因为它是已检查的异常_Java_Multithreading_Interrupt - Fatal编程技术网

Java 我希望我的线程能够处理中断,但我可以';t捕获InterruptedException,因为它是已检查的异常

Java 我希望我的线程能够处理中断,但我可以';t捕获InterruptedException,因为它是已检查的异常,java,multithreading,interrupt,Java,Multithreading,Interrupt,我有一个Java线程,它调用 t.interrupt(); 使t(不同的线程)被中断。我希望“t”线程捕获一个InterruptedException,但是Eclipse不允许我将InterruptedException放入try主体中。如何调用InterruptedException?我是否使用了t.interrupt()错误 您可以调用Thread.interrupted()或Thread.getCurrentThread().isInterrupted()(前者将清除中断标志,后者将不清

我有一个Java线程,它调用

t.interrupt();

使t(不同的线程)被中断。我希望“t”线程捕获一个
InterruptedException
,但是Eclipse不允许我将
InterruptedException
放入try主体中。如何调用
InterruptedException
?我是否使用了
t.interrupt()
错误

您可以调用
Thread.interrupted()
Thread.getCurrentThread().isInterrupted()
(前者将清除中断标志,后者将不清除),如果设置了中断标志,则返回true。如果调用了抛出InterruptedException的方法(如
sleep

),则只能捕获
InterruptedException,因为InterruptedException只从特定的方法调用中抛出,大部分是等待、睡眠或执行I/O的方法调用,因此不会从任何地方抛出


如果您试图中断的线程正在执行CPU实际操作,而不是I/O操作,则需要在其中插入
Thread.getCurrentThread().isInterrupted()
调用,否则目标线程可能永远不会注意到。

虽然其他答案正确,但更全面的解释是合适的

线程只能在其执行的特定点被安全地中断(一般意义上)。特别是,当它发出了
wait()
调用,或者调用了可以发出
wait()
的服务时,可以安全地中断它。这就是为什么
InterruptedException
是选中的异常,而不是运行时(未选中)异常。允许线程在任何时候被任意中断都会使执行变得不确定(至少JVM是这样指定的)。有一种
Thread#stop()
方法被强烈反对,因为它导致的问题比解决的问题多。来自Javadoc

这种方法本质上是不安全的。使用thread.stop停止线程会导致它解锁所有已锁定的监视器(这是未经检查的ThreadDeath异常向堆栈上传播的自然结果)。如果以前受这些监视器保护的任何对象处于不一致的状态,则其他线程会看到损坏的对象,从而可能导致任意行为。stop的许多用法都应该被简单地修改某些变量以指示目标线程应该停止运行的代码所取代。目标线程应该定期检查该变量,如果该变量指示它将停止运行,则以有序的方式从其run方法返回。如果目标线程等待很长时间(例如,在条件变量上),则应使用中断方法中断等待。有关详细信息,请参阅

如果需要中断正在运行的线程,则必须使用
thread.interrupted()
.isInterrupted()
定期轮询中断状态,或轮询共享变量,并自行采取适当的操作


注意:上面的术语“interrupted”(除了作为方法名的一部分)是一般意义上的,而不是调用
线程#interrupt()

的具体含义。我真的不喜欢接受的答案,所以我想我应该投入$0.02

我想让“t”线程捕获InterruptedException,但Eclipse不允许我在try主体中加入InterruptedException。如何调用InterruptedException?我用t.interrupt()错了吗

重要的是要认识到,
t.interrupt()
只设置线程中的中断位——实际上它并不中断线程本身的处理。线程可以在任何时候安全地中断

引自:

  • 如果该线程在调用对象类的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中被阻塞,那么该线程的中断状态将被设置,并且它将立即从选择操作返回,可能带有非零值,就像调用了选择器的唤醒方法一样

  • 如果前面的条件都不成立,那么将设置该线程的中断状态

必须补充的是,如果线程的中断位已设置,然后调用
wait()
(和其他)时,
wait()
将立即抛出
InterruptedException

因此,您不能到处捕获
InterruptedExeption
,因为只有某些方法才会抛出它。如果您想查看某个线程是否被中断(再次设置了中断位),那么正确的做法是直接使用
线程.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;
     }
}
关于这个话题,有很多好的问题和答案:


能否请您粘贴带有锁销的钻头?可能的重复也与以下有关:螺纹可以随时“安全”中断。下一个
wait()
或其他程序将抛出。您还可以检查
Thread.currentThread().isInterrupted()
。您的线程处于处理循环中或正在等待。如果在处理循环中,则每次迭代检查一次标志