首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >有没有一种简单的方法可以把Future<Future<T>>变成Future<T>?

有没有一种简单的方法可以把Future<Future<T>>变成Future<T>?
EN

Stack Overflow用户
提问于 2010-01-30 05:07:49
回答 5查看 3.8K关注 0票数 19

我有一些代码可以将请求提交给另一个线程,该线程可能会也可能不会将该请求提交给另一个线程。这将产生Future<Future<T>>的返回类型。有没有什么非可恶的方法可以立即将其转换为等待整个未来链完成的Future<T>

我已经在使用Guava库来处理其他有趣的并发事情,并且作为Google Collections的替代品,它工作得很好,但我似乎找不到适合这种情况的东西。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-08-08 03:44:54

Guava13.0添加了Futures.dereference来实现这一点。它需要一个ListenableFuture<ListenableFuture>,而不是普通的Future<Future>。(在普通Future上操作需要一个makeListenable调用,每个调用都需要一个用于任务生命周期的专用线程(新方法的新名称JdkFutureAdapters.listenInPoolThread使其更加清晰)。)

票数 5
EN

Stack Overflow用户

发布于 2010-02-09 22:55:07

另一种可能的实现是使用guava库,它要简单得多。

代码语言:javascript
复制
import java.util.concurrent.*;
import com.google.common.util.concurrent.*;
import com.google.common.base.*;

public class FFutures {
  public <T> Future<T> flatten(Future<Future<T>> future) {
    return Futures.chain(Futures.makeListenable(future), new Function<Future<T>, ListenableFuture<T>>() {
      public ListenableFuture<T> apply(Future<T> f) {
        return Futures.makeListenable(f);
      }
    });
  }
}
票数 7
EN

Stack Overflow用户

发布于 2010-02-09 08:19:30

我认为这是实现未来合同的最好办法。我采取了尽可能不聪明的策略,以确保它符合合同的要求。尤其是get with timeout的实现。

代码语言:javascript
复制
import java.util.concurrent.*;

public class Futures {
  public <T> Future<T> flatten(Future<Future<T>> future) {
    return new FlattenedFuture<T>(future);
  }

  private static class FlattenedFuture<T> implements Future<T> {
    private final Future<Future<T>> future;

    public FlattenedFuture(Future<Future<T>> future) {
      this.future = future;
    }

    public boolean cancel(boolean mayInterruptIfRunning) {
      if (!future.isDone()) {
        return future.cancel(mayInterruptIfRunning);
      } else {
        while (true) {
          try {
            return future.get().cancel(mayInterruptIfRunning);
          } catch (CancellationException ce) {
            return true;
          } catch (ExecutionException ee) {
            return false;
          } catch (InterruptedException ie) {
            // pass
          }
        }
      }
    }

    public T get() throws InterruptedException, 
                          CancellationException, 
                          ExecutionException 
    {
      return future.get().get();
    }

    public T get(long timeout, TimeUnit unit) throws InterruptedException, 
                                                     CancellationException, 
                                                     ExecutionException, 
                                                     TimeoutException 
    {
      if (future.isDone()) {
        return future.get().get(timeout, unit);
      } else {
        return future.get(timeout, unit).get(0, TimeUnit.SECONDS);
      }
    }

    public boolean isCancelled() {
      while (true) {
        try {
          return future.isCancelled() || future.get().isCancelled();
        } catch (CancellationException ce) {
          return true;
        } catch (ExecutionException ee) {
          return false;
        } catch (InterruptedException ie) {
          // pass
        }
      }
    }

    public boolean isDone() {
      return future.isDone() && innerIsDone();
    }

    private boolean innerIsDone() {
      while (true) {
        try {
          return future.get().isDone();
        } catch (CancellationException ce) {
          return true;
        } catch (ExecutionException ee) {
          return true;
        } catch (InterruptedException ie) {
          // pass
        }
      }
    }
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2165167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档