这是否适当使用Thread.interrupt()?

时间:2014-09-04 23:50:18

标签: java multithreading

只要线程没有中断,我就想运行一段代码。目前我正在做的是:

while(!Thread.interrupted()){
    // .. some code
    try {
        Thread.sleep(4000);
    } catch(InterruptedException ex){
        break;
    }
    // .. some more code
}

我的问题是:这是一个好习惯吗?是否适当使用interrupt

3 个答案:

答案 0 :(得分:2)

是的,我认为这是interrupt()的目的,所以它似乎是合法用法。

答案 1 :(得分:1)

从概念上讲,这是在正确的轨道上。但是,有一些细节可以改进。

正确的是,线程中断机制被用来告诉线程做其他事情,并且线程可以在它选择的时候响应它的喜好。在这种情况下,从InterruptedException捕获Thread.sleep()并打破循环是完全合理的事情。它通常比通常做的更好,也就是完全忽略异常。 (这通常是错误的。)

可能存在的问题是循环条件检查线程是否已被中断。这可能是一个问题,具体取决于some codesome more code正在做什么。根据检测到中断时执行的代码块,您的系统可能处于不同的状态。

除非你的循环的一次迭代运行了很长时间(除了睡眠),否则通常只需要在循环中有一个中断点。在这种情况下,如果线程在进行some code处理时被中断,则会在调用InterruptedException后立即生成Thread.sleep()。所以你可以把循环条件改为while (true)并让catch-block脱离循环。 (如果这样做,你还应该重新插入中断位;见下文。)

或者,如果您只想检查循环顶部的中断,可以这样做:

while (!Thread.interrupted()) {
    // .. some code
    try {
        Thread.sleep(4000L);
    } catch (InterruptedException ie) {
        Thread.currentThread().interrupt();
    }
    // .. some more code
}

这使得循环中只有一个退出点,这可能使代码更易于推理。

请注意,此处使用的技术是在捕获InterruptedException重新置位线程上的中断位。关于处理中断的一般规则是应该重新置位中断位,或者应传播InterruptedException。如果两者都没有完成,那么调用代码可能会在后续wait()调用中被阻止,而不知道它曾被中断过。这通常是一个错误。

答案 2 :(得分:0)

良好做法是使用较新的更高级别的API,例如ExecutorService。您不应该使用较低级别的API,例如主题或synchronizewait / notify