Java 转换可列出的计划未来<;无效>;未来上市<;SomethingElse>;

Java 转换可列出的计划未来<;无效>;未来上市<;SomethingElse>;,java,guava,Java,Guava,我希望得到您对以下问题和解决方案(潜在)的反馈 假设有一个可运行的任务,它对CPU使用情况进行采样并将其写入CSV文件。此任务不返回任何结果。这需要定期执行,直到永远。如果用户取消任务,我们将关闭文件编写器,用户可以下载CSV文件 当您将这样的任务提交给ListengScheduledExecutorService(如下所示)时,您会得到一个ListenableScheduledFuture,它表示任务的结果 ListenableScheduledFuture<Void> futur

我希望得到您对以下问题和解决方案(潜在)的反馈

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

当您将这样的任务提交给ListengScheduledExecutorService(如下所示)时,您会得到一个ListenableScheduledFuture,它表示任务的结果

ListenableScheduledFuture<Void> future = (ListenableScheduledFuture<Void>) scheduledExecutorService
            .scheduleAtFixedRate(task, initialDelay, interval, timeUnit); 
ListenableScheduledFuture未来=(ListenableScheduledFuture)scheduledExecutorService
.scheduleAtFixedRate(任务、初始延迟、间隔、时间单位);
我们注册一个对未来的回调,这样当任务被取消时,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);
Function transformFunc=新函数()
{
@凌驾
公共文件应用(无效arg0)
{
返回文件;
}
};
ListenableScheduledFutureToListen=(ListenableScheduledFuture)Futures.transform(future,transformFunc);
//向ListenableScheduledFuture注册回调
Futures.addCallback(futureToListen、callback、executorService);
注意:根据Guava API文档,取消futureToListen将导致我们的任务被取消

问题:

  • 因为任务结果是空的,所以如上所示转换为ListenableScheduledFuture有意义吗

  • 将返回void的任务的未来转换为某种类型的未来在语义上有意义吗

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


  • transform
    可能无法实现您想要的功能。您提到取消未来登录将取消未来登录,这是事实。问题是,准备金也是如此:当
    future
    被取消时,
    futuretosten
    也将被取消。这意味着它永远不会计算结果

    要解决此问题,您有两个选项:

  • 如果您不想取消
    future
    ,请将
    futuretosten
    更改为
    SettableFuture
    。然后让取消
    future
    的人也调用
    futuretoliten.set(文件)
  • 如果您确实关心是否能够取消
    future
    ,那么将
    futuretListen
    更改为
    AbstractFuture
    ,它(a)公开
    set()

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

    谢谢@ChrisPovrik。我选择选项2是因为“未来”需要取消(选项1意味着即使“未来列表”已取消,我的任务仍将继续运行)。