如何中断线程并捕获Runnable对象中的中断

时间:2012-11-20 14:17:51

标签: java multithreading

我有几个实现Runnable接口的对象,我在单独的Threads中执行它们。基本上在Runnable对象的run()方法中,我做了一些网络活动,包括调用在等待输入时阻塞的方法(来自网络)。请注意,我没有任何故意暂停,即Thread.sleep()来电。任何暂停都是由对可能阻止的方法的调用引起的。

这些Runnable对象在GUI的控制之下,因此GUI界面和我希望提供给用户的一个功能是能够结束执行我的Runnable对象的线程但是我无法理解这样做。

一个显而易见的方法是调用Runnable对象Thread的Thread.interrupt()方法,但是对Thread方法的调用如何传播到Runnable对象?例如,我不能使用try-catch,似乎不允许在Runnable对象中捕获InterruptedException;我的IDE(netbeans)抱怨InterruptedException方法永远不会抛出run()

我的代码如下,为简洁而剥离。 以下行在GUI线程的GUI代码中执行:

digiSearch = new DigiSearch(hostIP,this);
digiSearchThread = new Thread(digiSearch);
digiSearchThread.start();

以下是我的Runnable类,我希望/需要捕获其执行线程的中断。

public class DigiSearch implements Runnable {

private String networkAdapterIP;
private DigiList digiList;

public DigiSearch (String ipAddress, DigiList digiList){
    networkAdapterIP = ipAddress;
    this.digiList = digiList;
}
@Override
public void run() {

    try{
        /*
 * Do some network and other activities here which includes calling some blocking methods.  However I would like to interrupt the run() method if possible by calling Thread.interrupt()
*/


    }  catch (Exception ex){
       digiList.digiListException(ex);
    } catch (Throwable t){
       System.out.println("Search thread interrupted");
    }
}

}

有人可以告诉我如何实现这一点,或者解决我对中断线程的误解吗?

2 个答案:

答案 0 :(得分:6)

你有任何抛出IOException的阻止方法吗?如果是这样,这可能是您的InterruptedException占位符。其中许多方法是在引入InterruptedException之前编写的,因此不是更新会破坏遗留代码的接口,而是将InterruptedException包装在IOException中。

如果情况并非如此,那么你就会陷入困境。例如,如果你编写一个Runnable来创建一个只能工作且永不休眠的无限循环,则中断该线程将不会产生InterruptedExceptionRunnable负责定期检查Thread.interrupted()

答案 1 :(得分:3)

这里要注意几点:

1)虽然我同意为用户提供一个停止执行线程的功能很有用,但我建议考虑线程已经在执行的操作。是否可以回滚动作?是否可以忽略该操作并停止执行?

2)Thread.stop()和Thread.destroy()等是不推荐使用的方法(http://docs.oracle.com/javase/6/docs/api/

那么通常如何中断线程执行?输入易失性状态变量。

public class MyClass implements Runnable {
    private volatile boolean isAlive=true;

   /**
    * Request thread stop by calling requestThreadStop() externally.
    */
    public void requestThreadStop() {
        isAlive = false;
    }

    @Override
    public void run() {
        while(isAlive) {
            //Do All your thread work
            //if isAlive is modified, the next iteration will not happen
        }
    }
}

对于许多用例,上述实现有效。但是,如果run()方法循环中的工作只是一次迭代并且可能会阻塞很长时间,那么用户必须等到操作完成。

一旦用户请求从GUI终止,有没有办法静默地丢弃线程的执行?也许。您将不得不使用Threadpool进行探索。使用ExecutorService,您可以为shutdown()和shutdownNow()方法提供挂钩。

为避免重复,您可以从此previoud stackoverflow帖子中找到有关此线程池功能的更多信息How to stop the execution of Executor ThreadPool in java?