From Future.cancel()のJavaドキュメント
boolean cancel(boolean mayInterruptIfRunning)
このタスクの実行をキャンセルしようとします。タスクがすでに完了している場合、すでにキャンセルされている場合、またはその他の理由でキャンセルできなかった場合、この試行は失敗します。成功し、cancelが呼び出されたときにこのタスクが開始されていない場合、このタスクは実行されません。タスクがすでに開始されている場合、mayInterruptIfRunningパラメーターは、タスクを停止するために、このタスクを実行しているスレッドを中断する必要があるかどうかを決定します。
私の質問は、mayInterruptIfRunningがfalseの場合、キャンセルは何をするのですか?
タスクがすでに実行されている場合、タスクの実行をキャンセルまたは停止するにはどうすればよいですか?
中断していない場合は、キャンセルされた未来を通知するだけです。 isCancelled()
で確認できますが、手動で確認しないと何も起こりません。
以下のサンプルコードは、その方法を示しています。
private static FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
while (!task.isCancelled()) {
System.out.println("Running...");
Thread.sleep(1000);
}
return "The End";
}
});
public static void main(String[] args) throws InterruptedException {
new Thread(task).start();
Thread.sleep(1500);
task.cancel(false);
}
タスクが開始され、1.5回の反復後に停止するように指示されます。スリープを継続し(中断した場合はスリープしません)、その後終了します。
私の質問は、mayInterruptIfRunningがfalseの場合、キャンセルは何をするのですか?すでに実行されている場合、タスクの実行をキャンセルまたは停止するにはどうすればよいですか?
タスクがすでに実行を開始していて、mayInterruptIfRunning
がfalse
の場合、何もする必要はありません。 Javaでは、スレッドを中断することが、完了前にスレッドを停止する唯一の安全な方法であると考えられています。それでも、実装固有の間隔で中断をチェックすることにより、タスクが「準拠」する必要があります。
タスクがすでに開始されていて、mayInterruptIfRunningがfalseの場合、何も実行されません。
以下はcancel()です
public boolean cancel(boolean mayInterruptIfRunning) {
if (state != NEW)
return false;
if (mayInterruptIfRunning) {
if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))
return false;
Thread t = runner;
if (t != null)
t.interrupt();
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state
}
else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))
return false;
finishCompletion();
return true;
}
mayInterruptIfRunningがfalseの場合、cancel()は状態をNEWからCANCELEDに変更し、falseを返すだけで、他には何も実行されないことがわかります。