ExecutorService 控制的 CompletableFuture 的取消

2 java concurrency java.util.concurrent

我有一个ExecutorService将计算数据转发到 a CompletableFuture

class DataRetriever {
    private final ExecutorService service = ...;

    public CompletableFuture<Data> retrieve() {
        final CompletableFuture<Data> future = new CompletableFuture<>();

        service.execute(() -> {
            final Data data = ... fetch data ...
            future.complete(data);
        });
        return future;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望客户/用户能够取消任务:

final DataRetriever retriever = new DataRetriever();
final CompletableFuture<Data> future = retriever().retrieve();

future.cancel(true);
Run Code Online (Sandbox Code Playgroud)

这是行不通的,因为这会取消CompletableFuture执行程序服务中计划的外部未来,但不会取消内部未来。

cancel()是否有可能以某种方式将外部未来传播到内部未来?

Sav*_*ior 5

CompletableFuture#cancel实际上仅起到将 a 标记为已取消的目的CompletableFuture。它不执行任何操作来通知正在执行的任务停止,因为它与任何此类任务都没有关系。

javadoc暗示了这一点

mayInterruptIfRunning - 该值在此实现中无效,因为不使用中断来控制处理。

您的示例中的内部未来是 a ,而不是 a 并且它确实与执行( 或)有关。在内部,由于它知道任务正在执行什么,因此它可以向其发送 an尝试停止它。FutureCompletableFutureRunnableCallableThreadinterrupt

一种选择是返回某种类型的元组(例如某些 POJO),它提供对您的引用CompletableFuture和对Future返回的ExecutorService#submit. 如果需要,您可以使用Futureto 。cancel您必须记住 tocancelcompleteyour CompletableFuture,以便代码的其他部分不会永远被阻止/匮乏。