gpt4 book ai didi

java - 编写可变数量的 ListenableFuture

转载 作者:行者123 更新时间:2023-12-02 02:32:15 27 4
gpt4 key购买 nike

我对 Futures 很陌生,并且陷入了链接调用和创建对象列表的困境。我使用的是 Android,API 最小值为 19。

我想编写下面的方法getAllFoo():

ListenableFuture<List<Foo>> getAllFoo() {
// ...
}

我有这两种方法可用:

ListenableFuture<Foo> getFoo(int index) {
// gets a Foo by its index
}

ListenableFuture<Integer> getNbFoo() {
// gets the total number of Foo objects
}

方法Futures.allAsList()在这里会很好地工作,但我的主要限制是每次调用 getFoo(int index) 必须在前一个调用完成之前才能发生。

据我了解(并测试过),Futures.allAsList() “扇出”调用(所有调用同时开始),因此我不能使用类似的东西:

ListenableFuture<List<Foo>> getAllFoo() {
// ...

List<ListenableFuture<Foo>> allFutureFoos = new ArrayList<>();
for (int i = 0; i < size; i++) {
allFutureFoos.add(getFoo(i));
}

ListenableFuture<List<Foo>> allFoos = Futures.allAsList(allFutureFoos);

return allFoos;
}

我有这种(丑陋的)解决方案(有效):

// ...
final SettableFuture<List<Foo>> future = SettableFuture.create();

List<Foo> listFoos = new ArrayList<>();
addApToList(future, 0, nbFoo, listFoos);

// ...
private ListenableFuture<List<Foo>> addFooToList(SettableFuture future, int idx, int size, List<Foo> allFoos) {

Futures.addCallback(getFoo(idx), new FutureCallback<Foo>() {
@Override
public void onSuccess(Foo foo) {
allFoos.add(foo);
if ((idx + 1) < size) {
addFooToList(future, idx + 1, size, allFoos);
} else {
future.set(allFoos);
}
}

@Override
public void onFailure(Throwable throwable) {
future.setException(throwable);
}
});
return future;
}

如何使用 ListenableFuture 优雅地实现它?
我发现了多个相关主题(例如 thisthat ),但这些主题使用“编码”转换,并且不基于可变数量的转换。

如何编写 ListenableFutures 并获得与 Futures.allAsList() 相同的返回值,但通过链接调用(扇入)?

谢谢!

最佳答案

作为一般规则,最好将派生的 future 与 transform/捕捉/whennAllSucceed/whenAllComplete 链接在一起> 与手动 addListener/addCallback 调用相比。转换方法可以为您做更多事情:

  • 忘记设置输出从而挂起程序的机会更少
  • 传播取消
  • 避免保留内存超过所需时间
  • 采取一些技巧来减少堆栈溢出的可能性

无论如何,我不确定是否有一种特别优雅的方法来做到这一点,但我建议按照这些思路进行一些操作(未经测试!):

ListenableFuture<Integer> countFuture = getNbFoo();
return countFuture.transformAsync(
count -> {
List<ListenableFuture<Foo>> results = new ArrayList<>();
ListenableFuture<?> previous = countFuture;
for (int i = 0; i < count; i++) {
final int index = i;
ListenableFuture<Foo> current = previous.transformAsync(
unused -> getFoo(index),
directExecutor());
results.add(current);
previous = current;
}
return allAsList(results);
},
directExecutor());

关于java - 编写可变数量的 ListenableFuture,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46913218/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com