等待多个异步任务完成

我正在并行化我的操作,方法是将其拆分为确切的可用内核数,然后启动相同数量的 AsyncTask,对数据的不同部分执行相同的操作。

我正在使用,以便并行执行它们。executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ...)

我想知道每个线程何时完成其工作,以便合并所有结果并执行进一步的操作。

我该怎么办?


答案 1

您也可以简单地递减共享对象中的计数器,作为 的一部分。由于在同一线程(主线程)上运行,因此不必担心同步。onPostExecuteonPostExecute

更新 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正在寻找一种解决方案,在这个解决方案中,他可以避免构建一个新的类。这可以通过在生成的 s 之间共享一个来完成:AtomicIntegerAsyncTask

// 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"));    
        }
    }
}

答案 2

您应该使用CountDownLatch。以下是包含示例的文档:java.util.concurrent.CountDownLatch

基本上,您将CountDownLatch的引用提供给您的线程,并且每个线程在完成后都会递减它:

countDownLatch.countDown();

主线程将使用以下方法等待所有线程的终止:

countDownLatch.await();

推荐