Abh*_*iya 1 java multithreading sleep wait interrupted-exception
如果我编写如下代码,我们不能中断或终止线程。它也不会抛出 InterruptedException。
Thread loop = new Thread(
new Runnable() {
@Override
public void run() {
while (true) {
}
}
}
);
loop.start();
loop.interrupt();
Run Code Online (Sandbox Code Playgroud)
要中断这个线程,我需要修改我的代码如下:
Thread loop = new Thread(
new Runnable() {
@Override
public void run() {
while (true) {
if (Thread.interrupted()) {
break;
}
// Continue to do nothing
}
}
}
);
loop.start();
loop.interrupt();
Run Code Online (Sandbox Code Playgroud)
我的问题是,
为什么 Java 的设计方式是只有在像 sleep() 和 wait() 这样的阻塞方法的情况下才会抛出InterruptedException。
为什么在普通代码中,我们需要像上面的代码片段那样手动处理?为什么每当我们通过interrupt()方法将中断标志设置为 true 时,Java 不会抛出 InterruptedException ?
我已经阅读了很多关于 InterruptedException 的博客和文章,但没有找到任何令人信服的答案。
编辑
找到关于 InterruptedException 的好文章:http : //codepumpkin.com/interruptedexception-java-multithreading/
1) 为什么 Java 的设计方式是只有在像 sleep() 和 wait() 这样的阻塞方法的情况下才会抛出 InterruptedException。
重点thread.interrupt()是它是合作的。一个线程被中断,但它必须检查中断标志,Thread.currentThread().isInterrupted()以便它可以正确管理自己的终止并在必要时清理共享对象、锁、finally 块等。
中断是对线程的指示,它应该停止正在执行的操作并执行其他操作。它是由程序员来决定究竟是如何一个线程响应一个中断,但它是很常见的线程终止。
这些方法做投InterruptedException是正在等待的锁和其他条件的人。它们在被中断时抛出异常,因此线程可以在终止之前再次清理自己。
2)为什么在普通代码中,我们需要像上面的代码片段一样手动处理?为什么每当我们通过 interrupt() 方法将中断标志设置为 true 时,Java 不会抛出 InterruptedException?
另一种选择InterruptedException是 aRuntimeException可以随时抛出,而不管程序是否预料到它。与stop()其他不推荐使用的Thread方法的部分问题是它们倾向于违反各种语言结构,并且可能会使应用程序内存处于不良状态。这里有更多的细节。
同样可以说对InterruptedException,如果它是一个RuntimeException。您可以想象一个线程是否正在更改共享对象,然后只是在中途抛出意外RuntimeException或完全停止。正在更新的共享对象很容易处于无效状态。
Run Code Online (Sandbox Code Playgroud)if (Thread.interrupted()) {
这不是正确的调用方法,因为它会清除线程上的中断标志,这是一种错误模式。请使用以下内容:
Run Code Online (Sandbox Code Playgroud)if (Thread.currentThread().isInterrupted()) {
这会保留中断标志,如果可能的话应该这样做。此外,当InterruptedException抛出时也会清除中断标志。这就是为什么这是一个很好的模式:
try {
...
} catch (InterruptedException ie) {
// re-interrupt the thread to propagate the interrupt flag
Thread.currentThread().interrupt();
// handle the interrupt here by probably quitting the thread
}
Run Code Online (Sandbox Code Playgroud)
库“吞下”中断标志有很多问题。即使您的代码很小,它也可能会被复制到一个更大的块中,因此您总是可以将中断标志恢复为一个好的模式。