我有一些代码可以将请求提交给另一个线程,该线程可能会也可能不会将该请求提交给另一个线程。这将产生Future<Future<T>>
的返回类型。有没有什么非可恶的方法可以立即将其转换为等待整个未来链完成的Future<T>
?
我已经在使用Guava库来处理其他有趣的并发事情,并且作为Google Collections的替代品,它工作得很好,但我似乎找不到适合这种情况的东西。
发布于 2012-08-08 03:44:54
Guava13.0添加了Futures.dereference
来实现这一点。它需要一个ListenableFuture<ListenableFuture>
,而不是普通的Future<Future>
。(在普通Future
上操作需要一个makeListenable调用,每个调用都需要一个用于任务生命周期的专用线程(新方法的新名称JdkFutureAdapters.listenInPoolThread
使其更加清晰)。)
发布于 2010-02-09 22:55:07
另一种可能的实现是使用guava库,它要简单得多。
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);
}
});
}
}
发布于 2010-02-09 08:19:30
我认为这是实现未来合同的最好办法。我采取了尽可能不聪明的策略,以确保它符合合同的要求。尤其是get with timeout的实现。
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
}
}
}
}
}
https://stackoverflow.com/questions/2165167
复制相似问题