我有一个执行器服务
,它将计算出的数据转发到可完成的未来
:
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;
}
}
我希望客户端/用户能够取消任务:
final DataRetriever retriever = new DataRetriever();
final CompletableFuture<Data> future = retriever().retrieve();
future.cancel(true);
这不起作用,因为这将取消外部的可完成未来
,而不是executor服务中计划的内部未来。
是否有可能将外部未来的取消()
传播到内部未来?
使用我的Tascalate并发库,您的代码可以重写如下:
class DataRetriever {
private final ExecutorService service = ...;
public Promise<Data> retrieve() {
return CompletableTask.supplyAsync(() -> {
final Data data = ... fetch data ...
return data;
}, service);
}
}
Promise
和CompletableTask
,都是我的库中的类,您可以在我的博客中阅读更多内容
Pillar提到的另一个解决方案是扩展< code>CompletableFuture。这里有一个方法与您现有的代码非常相似。它还处理异常,这是一个不错的好处。
class CancelableFuture<T> extends CompletableFuture<T> {
private Future<?> inner;
/**
* Creates a new CancelableFuture which will be completed by calling the
* given {@link Callable} via the provided {@link ExecutorService}.
*/
public CancelableFuture(Callable<T> task, ExecutorService executor) {
this.inner = executor.submit(() -> complete(task));
}
/**
* Completes this future by executing a {@link Callable}. If the call throws
* an exception, the future will complete with that exception. Otherwise,
* the future will complete with the value returned from the callable.
*/
private void complete(Callable<T> callable) {
try {
T result = callable.call();
complete(result);
} catch (Exception e) {
completeExceptionally(e);
}
}
@Override
public boolean cancel(boolean mayInterrupt) {
return inner.cancel(mayInterrupt) && super.cancel(true);
}
}
然后,在DataRetriever
中,您只需执行以下操作:
public CompletableFuture<Data> retrieve() {
return new CancelableFuture<>(() -> {... fetch data ...}, service);
}
CompletableFuture#cancel
实际上仅用于将CompletableFuture标记为已取消。它不会通知正在执行的任务停止,因为它与任何此类任务都没有关系。
javadoc 暗示了这一点
mayInterruptIfRunning
- 此值在此实现中没有影响,因为中断不用于控制处理。
在你的示例中,内在的未来是
一个未来
,而不是一个CompletableFuture
,它确实与执行的Runnable
(或Callable)
有关系。在内部,由于它知道任务正在哪个线程
上执行,因此它可以向它发送中断
以尝试停止它。
一种选择是返回某种元组(例如一些POJO),该元组提供对您的
CompletableFuture
和由ExecutorService#提交
返回的Future
的引用。如果需要,您可以使用Future
来取消
。您必须记住取消
或完成
您的CompletableFuture
,以便您的代码的其他部分不会永远保持阻塞/饥饿状态。
问题内容: 我想使用asyncio调用loop.run_in_executor在Executor中启动一个阻塞函数,然后在以后取消它,但这似乎对我不起作用。 这是代码: 我希望上面的代码仅允许阻塞函数输出: 然后查看非阻塞函数的输出。但是,即使我取消了,阻碍性的未来仍在继续。 可能吗?还有其他方法吗? 谢谢 问题答案: 在这种情况下,一旦它真正开始运行,就无法取消它,因为您依赖的行为,并且它的文档
问题内容: 我一直在阅读文档并进行搜索,但似乎找不到直接的答案: 你可以取消已经执行的任务吗?(由于任务已开始,需要一段时间,因此需要取消一半) 我是从Celery FAQ的文档中找到的 但是我不清楚这是否会取消排队的任务,或者是否会杀死工作程序上正在运行的进程。感谢你能摆脱的光芒! 问题答案: 撤销将取消任务执行。如果任务被吊销,工人将忽略该任务并且不执行它。如果你不使用持久撤销,则可以在wor
如果网络连接已打开超过几个小时,我将使用关闭网络连接。然而,在大多数情况下,网络连接在达到超时之前就关闭了,因此我取消了。在这种情况下,我还希望executor服务终止并释放其线程池。 令我惊讶的是,这并不是开箱即用的:虽然我在调度任务后对executor服务调用了<code>shutdown(),但当其唯一调度的任务被取消时,executor不会自动终止。从这种行为甚至可能是正确的,因为可以说取
我有一个糟糕的服务人员,不再更新。我首先注意到了Chrome中的问题。然后,我将以下代码放入索引中。html文件和软件中的。js(服务工作者)文件。在大多数情况下,它似乎运行良好。Firefox似乎是唯一一个没有删除服务工作者的浏览器。我使用下面的文章创建了注销脚本。 如何卸载Service Worker? 我也用过这篇文章和代码,得到了同样的结果。 我如何删除一个有缺陷的服务人员,或者实现一个“
我正试图实现一个轮询机制。我想根据一些条件增加或减少轮询间隔。我使用mono.repeat with delayElements来执行带有间隔的重复任务。但我无法根据一些条件找到修改延迟的方法。
Feign介绍 Feign是一个声明式的web service客户端,它使得编写web service客户端更为容易。创建接口,为接口添加注解,即可使用Feign。Feign可以使用Feign注解或者JAX-RS注解,还支持热插拔的编码器和解码器。Spring Cloud为Feign添加了Spring MVC的注解支持,并整合了Ribbon和Eureka来为使用Feign时提供负载均衡。 译自:h