【问题标题】:Handling exceptions when chaining Futures in guava在番石榴中链接期货时处理异常
【发布时间】:2016-09-13 16:47:58
【问题描述】:

关于以下代码中的异常处理:

ListenableFuture<BufferedImage> imgFuture = downloadExecutor
                    .submit(new Downloader(url));
            ListenableFuture<BufferedImage> resizeFuture = Futures.transformAsync(
                    imgFuture, new AsyncFunction<BufferedImage, BufferedImage>()
                    {
                        @Override
                        public ListenableFuture<BufferedImage> apply(
                                BufferedImage input) throws Exception
                        {
                            ListenableFuture<BufferedImage> resizedFuture = null;
                            if (input != null)
                            {
                                resizedFuture = actionExecutor
                                        .submit(new ResizeImageAction(input));
                            }
                            return resizedFuture;
                        }
                    });

            ListenableFuture<BufferedImage> grayFuture = Futures
                    .transformAsync(resizeFuture, input -> {
                        return actionExecutor
                                .submit(new ToGrayImageAction(input));
                    });

假设提交给执行程序的每个操作都可以引发异常,那么这段代码将如何表现。

transformAsync() 方法是否知道不链接引发异常的空值或期货?在这里使用CheckedFuture 会帮助我吗?如果是,我应该如何使用它?

【问题讨论】:

    标签: java concurrency guava future


    【解决方案1】:

    它知道抛出的异常,但不知道空值,因为它是完全合法的值。如果在第一个ListenableFuture 中抛出异常,则它将传播到所有转换器:它们的onFailure 回调将被调用,但不会调用它们的转换(因为没有转换的值)。

    Javadoc 到transformAsync:

    @return 保存函数结果(如果输入成功)或原始输入失败(如果不是)的未来

    简单示例:

    ListenableFuture<Integer> nullFuture = executor.submit(() -> null);
    ListenableFuture<Integer> exceptionFuture = executor.submit(() -> {
        throw new RuntimeException();
    });
    
    // Replace first argument with exceptionFuture to get another result
    ListenableFuture<Integer> transformer = Futures.transformAsync(nullFuture, i -> {
        System.out.println(i);
        return Futures.immediateCheckedFuture(1);
    }, executor);
    
    Futures.addCallback(transformer, new FutureCallback<Integer>() {
        @Override
        public void onSuccess(Integer result) {
            System.out.println(result);
      }
    
        @Override
        public void onFailure(Throwable t) {
            System.out.println(t);
      }
    });
    

    对于nullFuture,将打印“null and 1”,而对于exceptionFuture,将仅打印“java.lang.RuntimeException”,因为异常已传播到其转换器。

    【讨论】:

    • hmmm 所以如果我想链接几个'transformAsync',我必须使用'Futures.addCallback()'?
    • @whomaniac 不,你不应该,这只是一个例子,表明如果抛出异常,转换将不会发生。回调仅用于打印,不适用于链式转换
    猜你喜欢
    • 2015-03-11
    • 2013-07-14
    • 2011-06-25
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多