Подождите, пока несколько AsyncTask завершатся

Я распараллеливаю свою операцию, разбивая ее на точное количество доступных сердечников, а затем, запустив такое же количество AsyncTask, выполнив одну и ту же операцию, но на разных частях данных.

Я использую executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ...) , чтобы распараллелить их выполнение.

Я хотел бы знать, когда каждый поток заканчивает свою работу, чтобы объединить все результаты и выполнить дальнейшие операции.

Как я могу сделать?

Solutions Collecting From Web of "Подождите, пока несколько AsyncTask завершатся"

Вы также можете просто уменьшить счетчик в общем объекте как часть onPostExecute . Поскольку onPostExecute работает в одном потоке (основной поток), вам не придется беспокоиться о синхронизации.

ОБНОВЛЕНИЕ 1

Общий объект может выглядеть примерно так:

 public class WorkCounter { private int runningTasks; private final Context ctx; public WorkCounter(int numberOfTasks, Context ctx) { this.runningTasks = numberOfTasks; this.ctx = ctx; } // Only call this in onPostExecute! (or add synchronized to method declaration) public void taskFinished() { if (--runningTasks == 0) { LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(this.ctx); mgr.sendBroadcast(new Intent("all_tasks_have_finished")); } } } 

ОБНОВЛЕНИЕ 2

Согласно комментариям для этого ответа, OP ищет решение, в котором он может избежать создания нового класса. Это можно сделать, разделив AtomicInteger среди порожденных AsyncTask s:

 // TODO Update type params according to your needs. public class MyAsyncTask extends AsyncTask<Void,Void,Void> { // This instance should be created before creating your async tasks. // Its start count should be equal to the number of async tasks that you will spawn. // It is important that the same AtomicInteger is supplied to all the spawned async tasks such that they share the same work counter. private final AtomicInteger workCounter; public MyAsyncTask(AtomicInteger workCounter) { this.workCounter = workCounter; } // TODO implement doInBackground @Override public void onPostExecute(Void result) { // Job is done, decrement the work counter. int tasksLeft = this.workCounter.decrementAndGet(); // If the count has reached zero, all async tasks have finished. if (tasksLeft == 0) { // Make activity aware by sending a broadcast. LocalBroadcastManager mgr = LocalBroadcastManager.getInstance(this.ctx); mgr.sendBroadcast(new Intent("all_tasks_have_finished")); } } } 

Вы должны использовать CountDownLatch. Вот документация с примерами: java.util.concurrent.CountDownLatch

В основном вы указываете ссылку CountDownLatch на свои потоки, и каждый из них будет уменьшать ее по окончании:

 countDownLatch.countDown(); 

Основной поток будет ждать завершения всех потоков, используя:

 countDownLatch.await(); 

Еще одним вариантом может быть сохранение всех ваших новых потоков в массиве.

Затем вы можете перебирать массив и ждать с потоком [i] .join для завершения потока.

См. Join () http://developer.android.com/reference/java/lang/Thread.html#Thread(java.lang.Runnable)

Когда Итерация закончена, все ваши потоки выполнены, и вы можете