Pét*_*rök 147

这样做是为了保持状态.

当你捕获InterruptException并吞下它时,你基本上阻止任何更高级别的方法/线程组注意到中断.这可能会导致问题.

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

Java Concurrency in Practice第7.1.3章:响应中断中更详细地讨论了这一点.它的规则是:

只有实现线程中断策略的代码才可以吞下中断请求.通用任务和库代码永远不应吞下中断请求.

  • 在[文档](https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html)中,它声明_"按照惯例,通过抛出`InterruptedException`**退出的任何方法都会清除中断状态**当它这样做的时候.我认为这使得答案更明确_Why_你需要保留中断状态. (14认同)
  • “高级方法/线程组”是什么意思? (3认同)
  • 还值得注意的是,一旦您通过其他“传递机制”(“InterruptedException”)收到有关此状态的通知,并且希望或无法重新抛出它,则“interrupt()”调用是“设置”中断标志的唯一方法。 (2认同)

Aja*_*rge 65

我认为这个代码示例使事情变得清晰.完成工作的班级:

   public class InterruptedSleepingThread extends Thread {

        @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) {
                //e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

主类:

   public class InterruptedSleepingThreadMain {

        /**
         * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException {
            InterruptedSleepingThread thread = new InterruptedSleepingThread();
            thread.start();
            //Giving 10 seconds to finish the job.
            Thread.sleep(10000);
            //Let me interrupt
            thread.interrupt();
        }

    }
Run Code Online (Sandbox Code Playgroud)

尝试在不设置状态的情况下调用中断.

  • 所以结论是?? (11认同)
  • 谢谢。我现在明白你的意思了:https://repl.it/@djangofan/InterruptedThreadExample (3认同)
  • 这不是例子所描述的。如果吞下中断,外部函数将不会退出并继续执行`sleepBabySleep` (2认同)

Ber*_*t F 20

注意:

http://download.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

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

要使此技术起作用,任何捕获中断异常并且不准备立即处理它的方法都必须重新确认异常.我们说重申而不是重新抛出,因为并不总是可以重新抛出异常.如果没有声明捕获InterruptedException的方法抛出此(已检查)异常,那么它应该使用以下咒语"重新中断":

Thread.currentThread().interrupt();
Run Code Online (Sandbox Code Playgroud)

这可以确保Thread一旦能够就重新加入InterruptedException.