为什么在try / catch中使用Thread.currentThread()。isInterrupted()

时间:2017-08-01 14:40:12

标签: java multithreading

我发现这个结构在 Thinking in java 的多线程章节中很流行:

public void run(){
    try{
        while(!Thread.currentThread().isInterrupted()){
            // do something blocked like wait(), sleep() or I/O
        }
    }catch(InterruptedExeption e){

    }
}

但是我认为,当且仅当被阻止的wait()sleep()I/O抛出InterruptedExeption时,while循环才会退出,为什么不使用{{1}而不是?或者仅仅因为while(true)只是规范?

4 个答案:

答案 0 :(得分:3)

由于所有Runnable都是睡眠状态,因此检查中断是不必要的。但正如你从评论中可以看出的那样,这是一个更大的惯例的模型。当sleep和wait抛出InterruptedException时,阻塞I / O调用(在注释中列出)不会,并且不等待或休眠的CPU密集型代码也不会。

Bruce E在这里做的是为你提供一个模板,它可以处理抛出InterruptedException的情况(他用它来退出循环),还可以处理没有睡眠或等待的情况。没有抛出InterruptedException。它让读者知道他们可以选择明确检查标志,并演示正确的方法(与使用中断方法清除标志相反)。

答案 1 :(得分:0)

您也可以从外部用Thread.interrupt()中断线程。所以说它基本上是一个内置的布尔标志。

在这种情况下,你是对的。您可以使用while(true),因为它会在发生InterruptedException时突破循环。作者可能想在一个有凝聚力的问题上解释它。关于如何阻止无尽的线程,可能会有一章。

答案 2 :(得分:0)

这是一个人为的,相当糟糕的例子。你是对的,while (true)是一个非常好的替代品。

sleepwait 已经检查此标记。他们使用它来知道是否抛出异常。

因此这段代码:

public void run(){
    try{
        while(!Thread.currentThread().isInterrupted()){
            Thread.sleep(100);
        }
    }catch(InterruptedExeption e){

    }
}

基本上代表了这种逻辑(伪代码):

try {
    while(!Thread.currentThread().isInterrupted())
    {
        /* Thread.sleep */
        boolean keepSleeping = true;
        while(keepSleeping)
        {
            if (Thread.currentThread().isInterrupted())
            {
                throw new InterruptedExeption();
            }
            actualSleep(/*a very small amount of time*/);
            if (/* we've slept long enough*/)
            {
                keepSleeping = false;
            }
        }
        /* End Thread.sleep */
    }
}catch(InterruptedExeption e){

}

这显然有点复杂和毫无意义。

更重要的是,Thread.sleep实际上调用了interrupted而不是isInterrupted,因为实际上重置了标志,所以这是微妙的不同所以线程不会中断。

答案 3 :(得分:0)

显然是根据API Doc

  

如果在调用Object类的wait(),wait(long)或wait(long,int)方法,或者join(),join(long),join(long)时阻塞了这个线程,int),sleep(long)或sleep(long,int),此类的方法,然后其中断状态将清除,它将收到InterruptedException

因此isInterrupted()InterruptedException的返回值并不一定意味着同样的事情。有关更多其他条件,请参阅API文档。