未来与异步

Future and asynchronism

我使用外部 api(ESRI API 用于 Android),其中我有一个循环 return class 未来

...
for (Layer layer : layers) {

// ListenableFuture extends Future<V>
final ListenableFuture<FeatureQueryResult> future= gdbFeatureTable.queryFeaturesAsync(query);

future.addDoneListener(() -> {
                try {
                    FeatureQueryResult result = future.get();
...
}

try {
                FeatureQueryResult result = future.get();


    }
    ...

是否可以启动所有 queryFeaturesAsync 并在 for 循环后异步获取全局结果(result1 + result2 + 等等)? 最好的方法是什么?承诺?线程池执行器 ?

感谢您的帮助

我认为里面的方法 queryFeaturesAsync() 已经使用了 ThreadPoolService,并且使用 ThreadPoolService 从另一个 ThreadPoolService 中检索结果是多余的,恕我直言。

我建议您使用 AsyncTask 因为它是本机 Android SDK 工具并且使用起来非常简单:

AsyncTask<ListenableFuture<FeatureQueryResult>, Integer, List<FeatureQueryResult>> task =
        new AsyncTask<ListenableFuture<FeatureQueryResult>, Integer, List<FeatureQueryResult>>() {
    @Override
    protected List<FeatureQueryResult> doInBackground(ListenableFuture<FeatureQueryResult>[] futures) {
        int counter = 0;
        List<FeatureQueryResult> results = new ArrayList<>();
        for (ListenableFuture<FeatureQueryResult> future : futures) {
            try {
                results.add(future.get());
                publishProgress(++counter); // Optional feature
            } catch (ExecutionException | InterruptedException e) {
                Log.w("Huh?", "Interrupted!");
            }
        }
        return results;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        notifyMainThreadAboutProgress(values[0]); // Optional feature
    }

    @Override
    protected void onPostExecute(List<FeatureQueryResult> featureQueryResults) {
        doSomethingWithResultsInMainThread(featureQueryResults);
    }
};

ListenableFuture<FeatureQueryResult> future1 = gdbFeatureTable.queryFeaturesAsync(query);
ListenableFuture<FeatureQueryResult> future2 = gdbFeatureTable.queryFeaturesAsync(another_query);
ListenableFuture<FeatureQueryResult> future3 = gdbFeatureTable.queryFeaturesAsync(yet_another_query);

task.execute(future1, future2, future3);

我将 AsyncTask 设为匿名 class 以缩短示例。在生产中它必须是静态的 class.

如果我使用 CompletableFuture 是最好的方法吗? 全部看不懂...

List<CompletableFuture<FeatureQueryResult>> futures = new ArrayList<>();                
for (Layer layer : layers) {
    FeatureTable gdbFeatureTable = ((FeatureLayer) layer).getFeatureTable();
    CompletableFuture<FeatureQueryResult>  completableFuture = new CompletableFuture<>();
    ListenableFuture<FeatureQueryResult> future = gdbFeatureTable.queryFeaturesAsync(query);
    future.addDoneListener(() -> {
                        FeatureQueryResult result = future.get();
                        completableFuture.complete(result);
    }
    futures.add(future);
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));

你有另一个 completablefuture 的解决方案吗?

感谢您的回复