实现适用于 Android 应用的简单 HTTPREQUEST 队列时的并发问题



当我尝试从头开始为 http 请求实现队列时,我遇到了问题。抱歉,这对某些人来说可能是一个非常幼稚的并发问题。

基本上,我希望我的应用程序在任何时候只执行一个请求。额外的请求进入队列并在稍后执行。

我知道其他高级的东西,如FutureTask和执行池,但我想要答案,因为我对如何解决基本的并发问题感到好奇。以下是我的类维护请求队列

private Queue<HttpRequest> requestQueue;
private AsyncTask myAsyncTask=null;
public boolean send(HttpRequest hr){
   //if there isn't existing task, start a new one, otherwise just enqueue the request
   //COMMENT 1.
   if(myAsyncTask==null){
     requestQueue.offer(hr);
     myAsyncTask= new RequestTask();
     myAsyncTask.execute(null);
     return true;
   }
   else{
     //enqueue
     //COMMENT 2
     requestQueue.offer(hr);
   }
}
//nested class
RequestTask extends AsyncTask<boolean,void,void>{
      protected HttpResponse doInBackground(void... v){
           //send all request in the queue
           while(requestQueue.peek != null){
              HttpResquest r= requestQueue.poll
              //... leave out code about executing the request
           }
           return true;
      }
      protected void doPostExecute(boolean success){

           //COMMENT 3: if scheduler stop here just before myAsyncTask is set to null
           myAsyncTask=null;
      }
}

问题是,如果线程调度程序在 COMMENT 3 点停止后台线程(就在 myAsyncTask 设置为 null 之前)。

      //COMMENT 3: if scheduler stop here just before myAsyncTask is set to null
       myAsyncTask=null;

当时,其他线程碰巧转到点 COMMENT 1 并进入 if ...还。。。块。因为 myAsyncTask 没有设置为 null,所以任务会在 else 块(COMMENT 2) 中排队,但不会创建新的 asyncTask,这意味着队列将卡住!

   //COMMENT 1.
   if(myAsyncTask==null){
     requestQueue.offer(hr);
     myAsyncTask= new RequestTask;
     myAsyncTask.execute(null);
     return true;
   }
   else{
     //enqueue
     //COMMENT 2
     requestQueue.offer(hr);
   }

我希望这是清楚的。队列可能会停止处理。我很想知道如何避免这种情况。提前谢谢你

我通常实现这样的东西的方式是创建一个扩展线程的类。这将包含一个队列对象(使用您喜欢的任何对象),并且具有添加作业的方法。我会使用同步来确保所有线程安全。通知和等待可用于避免轮询。

这里有一个可能会有所帮助的示例...

    import java.util.*;
    public class JobProcessor extends Thread
    {
       private Queue queue = new LinkedList();
       public void addJob(Object job)
       {
           synchronized(queue)
           {
              queue.add(job);
              queue.notify(); // lests the thread know that an item is ready
           }
       }

       @Overide
       public void run()
       {
          while (true)
          {
              Object job = null;
              synchronized(queue) // ensures thread safety
              {
                 // waits until something is added to the queue.
                 try
                   while (queue.isEmpty()) queue.wait();
                 catch (InterruptedException e)
                   ; // the wait method can throw an exception you have to catch.
                 // but can ignore if you like.
                 job = queue.poll();
              }
              // at this point you have the job object and can process it!
              // with minimal time waiting on other threads.
              // be sure to check that job isn't null anyway!
              // in case you got an InterruptedException.
              ... processing code ...
              // job done loop back and wait for another job in the queue.
          }
       }
    }

您几乎只需要实例化这样的类并启动线程,然后开始插入对象来处理作业。当队列为空时,等待会导致此线程休眠(并且还会暂时释放同步锁),addJob 方法中的通知会在需要时将其唤醒。同步是一种确保只有一个线程可以访问队列的方法。如果您不确定它是如何工作的,请在 java SDK 参考中查找它。

您的代码中

没有任何线程安全代码(同步内容),这就是您的问题所在。它可能有点过于复杂,也无助于您调试它。但最主要的是您需要添加同步块,但请确保它们尽可能短。

最新更新