3

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

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

一种明显的方法是调用 Runnable 对象 Thread 的 Thread.interrupt() 方法,但是对 Thread 方法的调用如何传播到 Runnable 对象?例如我不能使用 try-catch,InterruptedException在 Runnable 对象中捕获似乎是不允许的;我的 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");
    }
}

}

有人可以启发我如何实现这一目标,或者解决我对中断线程的误解吗?

4

2 回答 2

6

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

如果不是这种情况,你就有点卡住了。例如,如果您编写一个Runnable创建一个只工作且永不休眠的无限循环的 a,则中断该线程不会导致InterruptedException. Runnable定期检查是公司的责任Thread.interrupted()

于 2012-11-20T14:35:08.040 回答
4

这里需要注意几点:

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 请求终止,有没有办法几乎立即静默放弃线程的执行?也许。为此,您将不得不探索使用线程池。使用 ExecutorService,您可以为 shutdown() 和 shutdownNow() 方法提供挂钩。

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

于 2012-11-20T15:17:13.803 回答