我有一些使用Java中断机制来完成我的工作的经验,但是我目前还不清楚什么时候应该设置当前线程的中断状态,什么时候应该抛出InterruptedException?
而且,为了让您更清楚,这是我之前编写的示例。
这是我开始工作之前的代码:
/*
* Run a command which locates on a certain remote machine, with the
* specified timeout in milliseconds.
*
* This method will be invoked by means of
* java.util.concurrent.FutureTask
* which will further submmited to a dedicated
* java.util.concurrent.ExecutorService
*/
public void runRemoteSript(String command, long timeout) {
Process cmd = null;
try {
cmd = Runtime.getRuntime().exec(command);
boolean returnCodeOk = false;
long endTime = System.currentTimeMillis() + timeout;
// wait for the command to complete
while (!returnCodeOk && System.currentTimeMillis() < endTime) {
// do something with the stdout stream
// do something with the err stream
try {
cmd.exitValue();
returnCodeOk = true;
} catch (IllegalThreadStateException e) { // still running
try {
Thread.sleep(200);
} catch (InterruptedException ie) {
// The original code just swallow this exception
}
}
}
} finall {
if (null != cmd) {
cmd.destroy();
}
}
}
我的意图是中断命令,因为一些远程脚本在完成之前会消耗大量时间。因此 runRemoteScript 可以完成或手动停止。这是更新的代码:
public void cancel(String cmd) {
// I record the task that I've previously submitted to
// the ExecutorService.
FutureTask task = getTaskByCmd(cmd);
// This would interrupt the:
// Thread.sleep(200);
// statement in the runRemoteScript method.
task.cancel(true);
}
public void runRemoteSript(String command, long timeout) {
Process cmd = null;
try {
cmd = Runtime.getRuntime().exec(command);
boolean returnCodeOk = false;
long endTime = System.currentTimeMillis() + timeout;
// wait for the command to complete
**boolean hasInterruption = false;**
while (!returnCodeOk && System.currentTimeMillis() < endTime) {
// do something with the stdout stream
// do something with the err stream
try {
cmd.exitValue();
returnCodeOk = true;
} catch (IllegalThreadStateException e) { // still running
try {
Thread.sleep(200);
} catch (InterruptedException ie) {
// The updated code comes here:
hasInterruption = true; // The reason why I didn't break the while-loop
// directly is: there would be a file lock on
// the remote machine when it is running, which
// will further keep subsequent running the same
// script. Thus the script will still running
// there.
}
}
}
// let the running thread of this method have the opportunity to
// test the interrupt status
if (hasInterruption) {
Thread.currentThread().interrupt();
}
// Will it be better if I throws a InterruptedException here?
} finall {
if (null != cmd) {
cmd.destroy();
}
}
}
关键是,设置调用线程测试的中断状态更好吗?或者只是向调用者抛出一个新的 InterrutedExeption?是否有任何最佳实践或特定情况更适合上述方法之一?
我会在这里写下我的理解,如果我误解了其中任何一个,您可以纠正我的理解。根据我的理解,我认为 thread.interrupt() 旨在不要求客户端代码处理中断,并且由客户端代码负责决定是否对其进行测试,而 throws InterruptedException 是必须的,因为它是检查异常?