Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 为什么要在catch InterruptException块中调用Thread.currentThread.interrupt()?_Java_Multithreading - Fatal编程技术网

Java 为什么要在catch InterruptException块中调用Thread.currentThread.interrupt()?

Java 为什么要在catch InterruptException块中调用Thread.currentThread.interrupt()?,java,multithreading,Java,Multithreading,为什么要调用catch块中的方法Thread.currentThread.interrupt()?这样做是为了保持状态 当捕获并吞下中断异常时,基本上可以防止任何更高级别的方法/线程组注意到该中断。这可能会引起问题 通过调用Thread.currentThread().interrupt(),您可以设置线程的中断标志,以便更高级别的中断处理程序会注意到它并可以适当地处理它 在第7.1.3章:中断响应中对此进行了更详细的讨论。其规则是: 只有实现线程中断策略的代码才能接受中断请求。一般用途的任务和

为什么要调用catch块中的方法
Thread.currentThread.interrupt()

这样做是为了保持状态

当捕获并吞下
中断异常时,基本上可以防止任何更高级别的方法/线程组注意到该中断。这可能会引起问题

通过调用
Thread.currentThread().interrupt()
,您可以设置线程的中断标志,以便更高级别的中断处理程序会注意到它并可以适当地处理它

在第7.1.3章:中断响应中对此进行了更详细的讨论。其规则是:

只有实现线程中断策略的代码才能接受中断请求。一般用途的任务和库代码不应吞没中断请求


我认为这是一个不好的练习,或者至少有点冒险。 通常更高级别的方法不执行阻塞操作,它们永远不会在那里看到中断异常。如果你在每一个你执行可中断操作的地方屏蔽它,你将永远不会得到它

Thread.currentThread.interrupt()
和不引发任何其他异常或以任何其他方式发出中断请求(例如,在线程的主循环中设置
interrupted
局部变量)的唯一理由是,您确实无法对异常执行任何操作,与
finally
块中的类似

如果您想更好地理解
Thread.currentThread.interrupt()
调用的含义,请参阅péter Török的答案。

注意:

如何停止等待很长时间(例如等待输入)的线程?

为了使这项技术发挥作用,任何捕捉到中断异常且不准备立即处理的方法都必须重新声明异常,这一点至关重要。我们说重述而不是重述,因为重述异常并不总是可能的如果捕获InterruptedException的方法未声明抛出此(已检查)异常,则应使用以下咒语“重新中断自身”:


这确保了线程将尽快重新释放InterruptedException。

我认为这个代码示例让事情变得有点清楚。 完成该工作的班级:

public class InterruptedSleepingRunner implements Runnable {
    @Override
    public void run() {
        doAPseudoHeavyWeightJob();
    }

    private void doAPseudoHeavyWeightJob() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            // You are kidding me
            System.out.println(i + " " + i * 2);
            // Let me sleep <evil grin>
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("Thread interrupted\n Exiting...");
                break;
            } else {
                sleepBabySleep();
            }
        }
    }

    protected void sleepBabySleep() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
尝试调用中断而不将状态设置回原位。

请参阅java文档

如果此线程在调用wait()、join()时被阻塞, 休眠(长),则其中断状态将被清除,并将 接收中断异常

如果该线程在I/O操作中被阻塞,则该线程的中断 状态将被设置,线程将收到 ClosedByInterruptException

如果该线程在选择器中被阻塞,则该线程的中断 将设置状态,并立即从选择返回 手术

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

因此,如果您将@Ajay George Answer中的sleepBabySleep()方法更改为I/O操作或仅更改为sysout,则无需将状态设置回原位即可停止程序。(顺便说一句,他们甚至不会抛出InterruptedException)


就像@péter Török所说的那样=>这样做是为了保持状态。(特别是对于抛出InterruptedException的方法)

中指出“按照惯例,任何通过抛出
InterruptedException
退出的方法都会在退出时清除中断状态。我认为这使答案更清楚地说明了为什么需要保留中断状态。另外值得注意的是,
interrupt()
call是在通过其他“传递机制”收到关于此状态的通知后设置中断标志的唯一方法-中断异常
并希望或不能重新抛出它。因此结论是??谢谢。我现在明白你的意思了:我想他的意思是
Thread.currentThread().interrupt()
允许您更快地退出线程,因此当捕获到
中断异常e
时,线程会立即停止。而如果
Thread.currentThread().interrupt()未使用,线程继续执行。。
public class InterruptedSleepingRunner implements Runnable {
    @Override
    public void run() {
        doAPseudoHeavyWeightJob();
    }

    private void doAPseudoHeavyWeightJob() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            // You are kidding me
            System.out.println(i + " " + i * 2);
            // Let me sleep <evil grin>
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("Thread interrupted\n Exiting...");
                break;
            } else {
                sleepBabySleep();
            }
        }
    }

    protected void sleepBabySleep() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
public class InterruptedSleepingThreadMain {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new InterruptedSleepingRunner());
        thread.start();
        // Giving 10 seconds to finish the job.
        Thread.sleep(10000);
        // Let me interrupt
        thread.interrupt();
    }
}