我有几个实现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");
}
}
}
有人可以告诉我如何实现这一点,或者解决我对中断线程的误解吗?
答案 0 :(得分:6)
你有任何抛出IOException
的阻止方法吗?如果是这样,这可能是您的InterruptedException
占位符。其中许多方法是在引入InterruptedException
之前编写的,因此不是更新会破坏遗留代码的接口,而是将InterruptedException
包装在IOException
中。
如果情况并非如此,那么你就会陷入困境。例如,如果你编写一个Runnable
来创建一个只能工作且永不休眠的无限循环,则中断该线程将不会产生InterruptedException
。 Runnable
负责定期检查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?