3

Callableインスタンス内で長時間実行される計算を検討してください。

そして、この計算の結果は、計算時間に応じてある程度の精度を持つ可能性があることを考慮してください。つまり、タスクがキャンセルされる場合、キャンセルする前にそれまでに計算されたものを返す必要があります (たとえば、計算する無理数のコンベアがあります)。

標準の Java 同時実行ユーティリティを使用してこのパラダイムを実装することが望ましいです。

Callable<ValuableResult> task = new Callable<>() { ... };
Future<ValuableResult> future = Executors.newSingleThreadExecutor().submit(task);
try {
    return future.get(timeout, TimeUnit.SECONDS);
} catch (TimeoutException te) {
    future.cancel(true);
    // HERE! Get what was computed so far
}

Futureとインターフェースを完全に再実装しなければ、ThreadPoolExecutorこの問題は解決できないようです。Java 1.7 でそのための便利な既存のツールはありますか?

4

3 に答える 3

1

この場合の最も簡単な方法は、このインスタンスfinal ResultWrapper内で渡されるオブジェクトを準備することです。Callable

final ValuableResultWrapper wrapper = new ValuableResultWrapper();
final CountDownLatch latch = new CountDownLatch(1);

Callable<ValuableResultWrapper> task = new Callable<>() { 
   ... 
   wrapper.setValue(...); // here we set what we have computed so far
   latch.countDown();
   return wrapper;
   ...  
};
Future<ValuableResultWrapper> future = Executors.newSingleThreadExecutor().submit(task);
try {
    return future.get(timeout, TimeUnit.SECONDS);
} catch (TimeoutException te) {
    future.cancel(true);
    // HERE! Get what was computed so far
    latch.await();
    return wrapper;
}

UPD : そのような実装 (複雑になります) では、ある種のラッチ (CountDownLatch私の例では) を導入して、そのタスクが完了する前に完了するようにする必要があります。return wrapper;

于 2014-07-29T11:55:06.927 に答える