Android 我如何启动两个异步线程,一旦它们都完成,它们就加入到公共执行中?

Android 我如何启动两个异步线程,一旦它们都完成,它们就加入到公共执行中?,android,asynchronous,Android,Asynchronous,我正在为以下场景寻找一种设计模式或方法。我希望为从不同来源检索数据启动两个独立的后台线程。然后,我希望在两个后台线程完成工作后调用一个方法(在UI线程上)。由于来自这两个源的数据必须组合在一起才有用,因此我必须等到两者都完成检索后,才能对数据进行操作。如何在Android平台上实现这一点?您可以使用AsyncTask和int来了解这两个作业是否都已完成…使用a,如下所示: CountDownLatch barrier = new CountDownLatch(2); // init with c

我正在为以下场景寻找一种设计模式或方法。我希望为从不同来源检索数据启动两个独立的后台线程。然后,我希望在两个后台线程完成工作后调用一个方法(在UI线程上)。由于来自这两个源的数据必须组合在一起才有用,因此我必须等到两者都完成检索后,才能对数据进行操作。如何在Android平台上实现这一点?

您可以使用
AsyncTask
int
来了解这两个作业是否都已完成…

使用a,如下所示:

CountDownLatch barrier = new CountDownLatch(2); // init with count=2
startWorkerThread1(barrier);
startWorkerThread2(barrier);
barrier.await(); // it will wait here until the count is zero
doStuffWithTheResult();

工作线程完成后,从中调用barrier.countDown()

编辑:我的第一个版本一直困扰着我,我不喜欢添加必要的布尔值,所以这里是另一个版本。使用每个添加任务的
onPostExecute
中的
this
调用它

ArrayList<AsyncTask> tasks;

public void doStuffWhenDone(AsyncTask finishedTask)
{
    tasks.remove(finishedTask);
    if(tasks.size() > 0)
        return;

    ... do stuff
}
ArrayList任务;
公共无效doStuffWhenDone(异步任务完成任务)
{
任务。删除(完成任务);
如果(tasks.size()>0)
返回;
…做事
}
我也会保留旧的,因为它们都能工作,但我认为上面的更干净。现在去整理我以前的一个项目

ArrayList<AsyncTask> tasks;
boolean hasBeenDone = false;

public void doStuffWhenDone()
{
    for(int i=0;i<tasks.size();i++)
        if(hasBeenDone || (tasks.get(i).getStatus() != AsyncTask.Status.FINISHED))
            return;

    hasBeenDone = true;
    ... do stuff
}
ArrayList任务;
布尔hasBeenDone=false;
公共无效doStuffWhenDone()
{

对于(int i=0;iYou可以使用AsyncTasks或普通线程以任何方式实现工作线程。也许AsyncTasks更好,因为它们使用线程池,所以初始化速度应该更快。是否
await()
阻止调用线程?除非您从另一个线程调用它(在UI中加上3个线程),UI将被阻止,这通常是不需要的。您是对的,需要第三个线程。AsyncTask非常适合此作业-在“doInBackground()”中,将调用barrier.await(),然后在“onPostExecute(result)”中对结果执行一些操作UI将被刷新。谢谢,以前没有听说过这个。不过,现在我想起来了,我相当确定这两个任务可能同时完成(好吧,一个接一个的机器指令)因此会导致“do stuff”代码执行两次。可能需要与原子布尔值相结合,以跟踪“do stuff”代码是否已执行。添加了更好的解决方案。这就是当我无法睡眠时发生的情况。lol,看起来更好。我唯一可能的查询是,是否使用doStuffWhenDone()同步as无法同时执行两个异步线程的
任务。删除(…)
之前,任何一个都会执行if语句,从而产生双重执行
do stuff
代码?仅当它是从
doInBackground
调用的,而不是像应该的那样从
onPostExecute
调用时。如果调用正确,它们都会在UI线程上按顺序运行。您可以将其作为故障保护添加进来来自程序员错误,而不是执行错误。