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() は、クライアント コードが割り込みを処理する必要がないことを意図していると思います。それをテストするかどうかを決定するのはクライアント コードの責任ですが、スローされた InterruptedException は必須です。チェック例外?