【问题标题】:How to chain Guava futures?如何链接番石榴期货?
【发布时间】:2015-03-11 07:59:33
【问题描述】:

我正在尝试创建一个小服务来接受文件上传,解压缩然后删除上传的文件。这三个步骤应该被链接为期货。我正在使用 Google Guava 库。

工作流程是:

future 下载文件,如果操作完成,则future 解压缩文件。如果解压完成,以后要删除原来上传的文件。

但老实说,我并不清楚我将如何链接未来,甚至如何以 Guava 的方式创建它们。文档简单明了且不清楚。好的,有transform 方法,但根本没有具体的例子。 chain 方法已弃用。

我想念RxJava 图书馆。

【问题讨论】:

标签: java guava future


【解决方案1】:

Futures.transform 不像 RxJava 那样可以流畅地链接,但您仍然可以使用它来设置相互依赖的 Futures。这是一个具体的例子:

final ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());

final ListenableFuture<FileClass> fileFuture = service.submit(() -> fileDownloader.download())
final ListenableFuture<UnzippedFileClass> unzippedFileFuture = Futures.transform(fileFuture, 
      //need to cast this lambda
      (Function<FileClass, UnzippedFileClass>) file -> fileUnzipper.unzip(file));
final ListenableFuture<Void> deletedFileFuture = Futures.transform(unzippedFileFuture, 
      (Function<UnzippedFileClass, Void>) unzippedFile -> fileDeleter.delete(unzippedFile));
deletedFileFuture.get(); //or however you want to wait for the result

此示例假定fileDownloader.download() 返回FileClass 的实例,fileUpzipper.unzip() 返回UnzippedFileClass 等。如果FileDownloader.download() 返回ListenableFuture&lt;FileClass&gt;,请使用AsyncFunction 而不是Function

为简洁起见,此示例还使用 Java 8 lambda。如果您不使用 Java 8,请传入 Function 或 AsyncFunction 的匿名实现:

Futures.transform(fileFuture, new AsyncFunction<FileClass, UpzippedFileClass>() {
        @Override
        public ListenableFuture<UnzippedFileClass> apply(final FileClass input) throws Exception {
            return fileUnzipper.unzip();
        }
    });

有关transform 的更多信息,请点击此处:http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/util/concurrent/Futures.html#transform(滚动或搜索“转换”——深度链接目前似乎已损坏)

【讨论】:

    【解决方案2】:

    为此,Guava 使用ListenableFuture 扩展了Future 接口。

    这样的事情应该可以工作:

    Runnable downloader, unzipper;
    ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
    
    service.submit(downloader).addListener(unzipper, service);
    

    我会在解压缩器中删除文件,因为它是一个近乎瞬时的动作,而且分离它会使代码复杂化。

    【讨论】:

      猜你喜欢
      • 2016-09-13
      • 2013-07-14
      • 1970-01-01
      • 2011-06-25
      • 2012-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多