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

时间:2015-08-12 21:28:12

标签: java android http android-asynctask sync

我有一组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) ){
 ...
}

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

编辑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中......

1 个答案:

答案 0 :(得分:1)

你熟悉信号量吗?基本上信号量有一个与之相关的数字。假设您有五个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.