Рассмотрим следующий код Java (упрощенная версия того, с чем я работаю - если есть ошибки, это потому, что я не запускал его через компилятор):
CountdownLatch latch = new CountdownLatch(collection.size());
for(Whatever thing : collection){
provider.doWork(thing, result -> {
process(result);
latch.countDown();
};
}
try {
latch.await();
} catch (InterruptedException ignore) {}
doMoreWork();
Поэтому я запускаю несколько асинхронных задач и жду, пока они все будут выполнены, прежде чем продолжить. Прямо сейчас я накапливаю результат асинхронных задач в списке. Это работает, и это нормально, но я смотрю, есть ли более чистая реализация с использованием Futures или чего-то подобного. Проблема в асинхронном вызове. Callable должен возвращать результат своей работы, но результат этой работы будет известен позже. Переписывать doWork на синхронность не стоит. Должен ли я просто оставить это в покое или есть вариант? Отчасти меня интересует лучший код, а отчасти я просто больше узнаю о параметрах параллелизма. Если это важно, это в приложении для Android.
Спасибо, читаю это сейчас. Если кто-то захочет предоставить какой-нибудь код, использующий этот класс, это будет приветствоваться.
К сожалению, supplyAsync доступен только в Android API уровня 24, и я не могу установить такой высокий минимальный уровень SDK - слишком много пользователей останется позади.
На самом деле зависит от ваших ограничений. Если это нормально, что метод, в котором это работает, является блокирующим, оставьте его в покое - код в порядке. Если метод не предназначен для блокировки, вы можете переписать его либо в форму, в которой метод возвращает будущее или наблюдаемое, либо принимает обратный вызов, который возвращает накопленные результаты. Однако это также потребует изменений на сайте вызывающего абонента.
Блокировать - нормально, это в фоновом потоке. Спасибо за ваш вклад.




Это подход с использованием ExecutorService и Future, не тестировался на Android, но все они доступны на уровне 1 api:
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<String>> pending = new ArrayList<Future<String>>();
for(Whatever thing : collection) {
Future<String> future = executor.submit(new Callable<String>() {
public String call() throws Exception {
return doWork();
}
});
pending.add(future);
}
for (Future<String> result : pending) {
System.out.println("Your result ASAP:" + result.get());
}
executor.shutdown();
Он вернется, как только текущий элемент будет выполнен, в том порядке, в котором они были отправлены.
Можете ли вы попробовать с помощью объекта completableFuture с методом supplyAsync. Это концепция Java 8, которая поможет вам решить вашу задачу.