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()是否有可能以某种方式将外部未来传播到内部未来?
CompletableFuture#cancel实际上仅起到将 a 标记为已取消的目的CompletableFuture。它不执行任何操作来通知正在执行的任务停止,因为它与任何此类任务都没有关系。
javadoc暗示了这一点
mayInterruptIfRunning- 该值在此实现中无效,因为不使用中断来控制处理。
您的示例中的内部未来是 a ,而不是 a ,并且它确实与执行( 或)有关。在内部,由于它知道任务正在执行什么,因此它可以向其发送 an尝试停止它。FutureCompletableFutureRunnableCallableThreadinterrupt
一种选择是返回某种类型的元组(例如某些 POJO),它提供对您的引用CompletableFuture和对Future返回的ExecutorService#submit. 如果需要,您可以使用Futureto 。cancel您必须记住 tocancel或completeyour CompletableFuture,以便代码的其他部分不会永远被阻止/匮乏。