gpt4 book ai didi

java - 将 ListenableScheduledFuture 转换为 ListenableFuture

转载 作者:太空宇宙 更新时间:2023-11-04 06:48:14 26 4
gpt4 key购买 nike

我想获得您对以下问题和解决方案(可能)的反馈。

假设有一个可运行任务对 CPU 使用情况进行采样并将其写入 CSV 文件。此任务不返回任何结果。这需要安排为永远定期执行。如果用户取消任务,我们将关闭文件编写器,用户可以下载 CSV 文件。

当你向 ListeningScheduledExecutorService 提交这样的任务时(如下所示),你会得到一个代表任务结果的 ListenableScheduledFuture 。

ListenableScheduledFuture<Void> future = (ListenableScheduledFuture<Void>) scheduledExecutorService
.scheduleAtFixedRate(task, initialDelay, interval, timeUnit);

我们注册一个回调到 future ,以便当任务被取消时,CSV文件就可以下载了:也就是说,我们需要将ListenableScheduledFuture转换为ListenableScheduledFuture。

Function<Void, File> transformFunc = new Function<Void, File>()
{
@Override
public File apply(Void arg0)
{
return file;
}
};

ListenableScheduledFuture<File> futureToListen = (ListenableScheduledFuture<File>) Futures.transform(future, transformFunc);

// register a callback to the ListenableScheduledFuture<File>
Futures.addCallback(futureToListen, callback, executorService);

注意:根据 Guava API DOC 1 ,取消 futureToListen 应该会导致我们的任务被取消。

问题:

  1. 由于任务结果为空,因此如上所示强制转换为 ListenableScheduledFuture 是否有意义?

  2. 将返回 void 的任务的 future 转换为某种类型的 future 在语义上有意义吗?

  3. 有更好、更优雅的解决方案吗?使用Java8的CompletableFuture会更好吗?

最佳答案

transform 可能不会做你想做的事。您提到取消 futureToListen 将取消 future,这是事实。问题是,保留也是如此:当 future 被取消时,futureToListen 也会被取消。这意味着它永远不会计算其结果。

要解决此问题,您有几个选择:

  1. 如果您不关心能否取消 future,请将 futureToListen 更改为 SettableFuture。然后让取消 future 的人也调用 futureToListen.set(file)
  2. 如果您确实关心能否取消 future,请将 futureToListen 更改为 AbstractFuture,它 (a) 公开 set()(以便您可以执行我在 (1) 中建议的操作),并且 (b) 实现 interruptTask() 来调用 future.cancel()

还有其他可能的聪明解决方案,涉及每当 future 完成不成功时触发工作,但我不确定我是否会推荐。我个人对于使用“Future 被取消”作为“工作已成功完成”的信号感到有点紧张。这是因为例如,Future 也可以通过执行程序关闭来取消。 (另一个原因:您需要小心区分“执行期间引发异常”和“被取消”。)因此,我建议的解决方案设置为直接调用 set(),而不是触发 future 的任何取消。

关于java - 将 ListenableScheduledFuture<Void> 转换为 ListenableFuture<SomethingElse>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23686704/

26 4 0