线程等待一组异步任务完成



我有一组HTTP请求,每个响应向ArrayList添加一个条目。之后我会用这个清单做一些检查。我怎样才能让程序等待,直到所有的请求都完成,并在继续检查之前填写列表?


编辑

代码示例:

class BackgroundTask extends AsyncTask<Void,String,Void>{
    List<Integer> responses;
    @Override
    protected synchronized Void doInBackground(Void... params) {
        responses= new ArrayList<Integer>();
        for( int i=0; i<10; i++ ){
            restAPI.getNextInt( // SEND HTTP REQUEST
                    new Response.OnSuccess() { // ON SUCCESS CALLBACK
                        @Override
                        public void onResponse(Integer i) {
                            responses.add(i);
                        }}, 
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                    }});
        }
        return null;
    }
    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
    }
}

在我的主线程中:

BackgroundTask bt = new BackGroundTask();
bt.execute();
bt.get(10000, TimeUnit.MILLISECONDS); // THIS DOESN'T WAIT
if( bt.responses.contains(10) ){
 ...
}

我之前没有提供代码,因为我在寻找通用的解决方案,而不是为我特定的


EDIT 2

这是我第二次尝试,它没有工作。我把所有东西都放在主线程中。

final Semaphore sema = new Semaphore(-params.size()+1);
final List<Integer> responses = Collections.synchronizedList(new ArrayList<Integer>());
for( final Param p : params ){
    new Thread(){
        @Override
        public void start(){
            restAPI.nextInt(p, // SEND HTTP REQUEST
                    new Response.OnSuccess() { // ON SUCCESS CALLBACK
                        @Override
                        public void onResponse(Integer i) {
                            System.out.print("aaaaa");
                            sema.release();
                            responses.add(i);
                        }}, 
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            sema.release();
                    }});
        }
    }.start();
}
try {
    sema.acquire();
} catch (InterruptedException e1) {
    e1.printStackTrace();
}
if( responses.contains(10) )  
...

现在发生的是sema.acquire()中的所有内容都阻塞/停止,aaaaa永远不会打印。如果我删除sema.acquire(),那么aaaaa打印。

整个代码是在protected void onPostExecute(Void result)AsyncTask如果这是重要的…

你熟悉信号量吗?基本上,一个信号量有一个与之相关联的数字。假设您有五个http请求要发出。您将初始化信号量的数字为-4。在需要等待列表被填充的主线程中,调用信号量的acquire方法。这将导致线程阻塞(等待),直到信号量的数值为1。在每个异步线程中,在异步线程完成将其条目添加到列表后,对信号量调用"release"。每次在信号量上调用release时,信号量的编号加1。因此,当所有异步线程都完成时,信号量的值将为1,允许主线程继续执行。为将来参考,在信号量上调用acquire将使该值减回零。

import java.util.concurrent.Semaphore;
Semaphore sema = new Semaphore(-4);
for each http request that needs to be made:
  spawn a separate thread to execute this function {
     do http request and insert entry into list
     sema.release();
  }
sema.acquire(); // block main thread until http requests are done
doStuff(); //The list is already filled, do whatever you need to do.

最新更新