okhttp同步和异步请求的区别

一、使用OkHttp

OkHttp发送请求后,可以通过同步或异步地方式获取响应。下面就同步和异步两种方式进行介绍。

1.1、同步方式

发送请求后,就会进入阻塞状态,知道收到响应。下面看一个下载百度首页的例子:

 
  1. OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();

  2. Request request = new Request.Builder().url("http://www.baidu.com")

  3. .get().build();

  4. Call call = client.newCall(request);

  5. try {

  6. Response response = call.execute();

  7. System.out.println(response.body().string());

  8. } catch (IOException e) {

  9. e.printStackTrace();

  10. }

  11. 上面的代码先创建OkHttpClient和Request对象,两者均使用了Builder模式;然后将Request封装成Call对象,然后调用Call的execute()同步发送请求,最后打印响应。

    1.2、异步方式

    异步方式是在回调中处理响应的,同样看下载百度首页的例子:

     
  12. OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();

  13. Request request = new Request.Builder().url("http://www.baidu.com")

  14. .get().build();

  15. Call call = client.newCall(request);

  16. call.enqueue(new Callback() {

  17. @Override

  18. public void onFailure(Call call, IOException e) {

  19. System.out.println("Fail");

  20. }

  21.  
  22. @Override

  23. public void onResponse(Call call, Response response) throws IOException {

  24.  
  25. System.out.println(response.body().string());

  26.  
  27. }

  28. });

  29. OKhttp中请求任务的管理是由dispatcher来负责的,负责请求的分发的发起。实际执行请求的是ConnctionPool

    同步请求

    同一时刻只能有一个任务发起,synchronized关键字锁住了整个代码,那么如果当前OkhttpClient已经执行了一个同步任务,如果这个任务没有释放锁,那么新发起的请求将被阻塞,直到当前任务释放锁

    
      @Override public Response execute() throws IOException {
        //同一时刻只能有一个任务执行 因为是阻塞式的 由synchronized关键字锁住
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already Executed");
          executed = true;
        }
        captureCallStackTrace();
        try {
          client.dispatcher().executed(this);
          Response result = getResponseWithInterceptorChain();
          if (result == null) throw new IOException("Canceled");
          return result;
        } finally {
          client.dispatcher().finished(this);
        }
      }
    

    异步请求

    同一时刻可以发起多个请求,因为异步请求每一个都是在一个独立的线程,由两个队列管理,并且synchronized只锁住了代码校验是否执行的部分。

    
      @Override public void enqueue(Callback responseCallback) {
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already Executed");
          executed = true;
        }
        //异步请求同一时刻可以有多个任务执行,由两个队列管理
        captureCallStackTrace();
        client.dispatcher().enqueue(new AsyncCall(responseCallback));
      }
    



     

猜你喜欢

转载自blog.csdn.net/boguesfei/article/details/81155264