呼び出しcancel()
たからFuture
といって、タスクが自動的に停止するわけではありません。タスクが停止することを確認するには、タスク内でいくつかの作業を行う必要があります。
cancel(true)
タスクに割り込みが送信されるように使用します。
- ハンドル
InterruptedException
。タスク内の関数がをスローする場合はInterruptedException
、例外をキャッチしたらできるだけ早く正常に終了するようにしてください。
Thread.currentThread().isInterrupted()
タスクが継続的な計算を行うかどうかを定期的に確認してください。
例えば:
class LongTask implements Callable<Double> {
public Double call() {
// Sleep for a while; handle InterruptedException appropriately
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
System.out.println("Exiting gracefully!");
return null;
}
// Compute for a while; check Thread.isInterrupted() periodically
double sum = 0.0;
for (long i = 0; i < 10000000; i++) {
sum += 10.0
if (Thread.currentThread().isInterrupted()) {
System.out.println("Exiting gracefully");
return null;
}
}
return sum;
}
}
また、他の投稿で言及されているようConcurrentModificationException
に、スレッドセーフクラスを使用している場合でもスローされる可能性があります。これはVector
、から取得するイテレータがVector
スレッドセーフではないため、同期する必要があるためです。拡張されたforループはイテレータを使用するため、次の点に注意してください。
final Vector<Double> vector = new Vector<Double>();
vector.add(1.0);
vector.add(2.0);
// Not thread safe! If another thread modifies "vector" during the loop, then
// a ConcurrentModificationException will be thrown.
for (Double num : vector) {
System.out.println(num);
}
// You can try this as a quick fix, but it might not be what you want:
synchronized (vector) { // "vector" must be final
for (Double num : vector) {
System.out.println(num);
}
}