压倒性的中断&线程类中的isInterrupted方法

时间:2014-04-29 16:10:00

标签: java multithreading

在我们的应用程序中,我们让线程执行特定操作。 收到事件后,我们需要中断正在进行的线程。 这些线程将通过调用“Thread.currentThread()。isInterrupted()”来检查它们的中断状态, 如果它被中断,则线程通过从run方法返回来停止。

我们现在看到的问题是这些线程可以在一个对象上等待()。 如果线程在对象上的wait()时被中断, 线程中断状态被重置并抛出InterruptedException。

由于     1)我们有很多地方线程可以在一个对象上等待     2)线程访问可以在对象上等待的其他对象的方法

我们决定覆盖中断()& isInterrupted()方法。 代码看起来像

public class MyThread extends Thread {

    private boolean isInterrupted = false;

    @Override 
    public void interrupt() {
        isInterrupted = true;
        super.interrupt();
    }

    @Override
    public boolean isInterrupted() {
        return isInterrupted;
    }

    public void run() {
        .........
        .........

        try {
            object1.wait();
        } catch (InterruptedException e) {
            /* if interrput() is not overrided, the interrupted flag 
            would be reset */
        }

        if(Thread.currentThread().isInterrupted()) {
            /* if interrupt is not overrided, isInterrupted would return
            false and the thread would continue to run. */
            return;
        }

        object2.method1(); // method1() can also wait on another object
        /* In method1() also we would need to check isInterrupted and get out
        quickly as soon as possible. This method1() will also be used by
        other threads which will not be interrupted. */

        if(Thread.currentThread().isInterrupted()) {
            return;
        }
        .........
        .........
    }
}

所以我的问题是

1)如上所述覆盖interrupt()和isInterrupted()是一个很好的代码吗?

2)当覆盖interrupt()时我们应该保持相同的行为,即throw    中断和其他异常,如java doc of interrupt()方法中所述    在Thread类中?实际上我们需要等待被中断的线程    但是要设置的中断标志。

3)Thread.interrupted()方法是静态的。     有了上面的重写,我们不应该使用这种方法吗?

3 个答案:

答案 0 :(得分:6)

首先,重写这些方法是一个非常糟糕的主意。

其次,我不明白为什么你的生活如此艰难:

try {
  doSomethingThatCanBlock();// e.g. wait()
}
catch(InterruptedException ex) {
  Thread.currentThread().interrupt(); // restore interrupt state
}

现在,下次检查Thread的中断状态时,它会告诉您相应的状态。就是这样。

答案 1 :(得分:0)

  

如果线程在对象的wait()中被中断,则线程中断状态将被重置并抛出InterruptedException。

恕我直言这句话表明你根本不需要任何中断。中断可以用来中止线程的执行,你似乎不想要它。传递一些消息......如果您想要灵活,请尝试EventBus。它允许您向发件人一无所知的程序部分发送消息。

也许你正在看一些全局变量 1 。请注意,使用Thread.interrupt也会处理全局变量(面对ThreadPool时变得无法使用)。

1包装成单身或类似物。

答案 2 :(得分:0)

根据您的评论,由于第三方jar未重新设置中断状态,您被迫覆盖方法。

总的来说,正如@Holger所提到的,捕获InterruptedException的方法应该恢复状态。

如果第三方jar没有设置状态,为什么不在第三方方法调用后重置标志?

thirdPartyInstance.method1();   
if (Thread.currentThread().isInterrupted()){
    Thread.interrupted();
}

这样您就可以将您的工作用作Runnable而非实际Thread(您不需要覆盖这些方法),您可以使用Thread.currentThread().isInterrupted()停止的方式你的主题。

最后 - 如果您计划继续扩展Thread并重写这些方法,

  1. 将状态布尔标志设为易失性
  2. 将您的isInterrupted()方法修改为

    @Override
    public boolean isInterrupted() {
        return isInterrupted || super.isInterrupted();
    }
    
  3. 如果线程状态由Thread.interrupted();清除,那么。