OkHttp synchronization usage method

OkHttp asynchronous usage method

  • Both onResponse and onFailure are executed in worker threads (child threads).

The difference between synchronous and asynchronous

  • The method call that initiates the request (Step 3)

    — Synchronous callcall.execute; The asynchronous callcall.enqueueAnd pass in a Callback object.
  • Block or not — synchronization blocks the current thread; Asynchrony does not block the current thread; instead, a new thread is opened to complete the network request.

The flow of asynchronous/synchronous requests

  • AsynCall is a Runnable.
  • The Dispatcher is the Dispatcher class that determines whether an asynchronous request is executed or ready.
  • Call is the interface, and the real operations are in its implementation class, RealCall.
  • A synchronous request is actually passedexecutedMethod to add the request (RealCall object) to the synchronous request queue (runningSyncCalls).

    – to entercall.executemethods
    • GetResponseWithInterceptorChain method: the interceptor chain, internal, in turn, calls the interceptor, after see in detail.

      “– Enter the Dispatcher method

      Synchronous request queue runningSyncCalls is defined in the Dispatcher class. There are three types of queues defined in the Dispatcher class (readyAsyncCalls asynchronous ready/cache waiting request queue, runningAsyncCalls asynchronous execution queue, and runningSyncCalls synchronous request queue).

      Enter the FINISHED method

      — before entering the callfinishedmethods

    1. Executed firstcall.remove(call)To remove the synchronization request from the current queue (promoteCalls=false), throws an exception if it cannot be removed.
    2. To performrunningCallsCount()Computes requests that are currently running.

      – to enterrunningCallsCountmethods
    • runningCallsCountMethod returns the sum of the number of asynchronous and synchronous requests being executed.
    1. whenrunningCallsCount == 0Indicates that there are no runnable requests in the Dispatch dispatcher class.

Summary of synchronous request steps

An asynchronous request

The key approach to asynchronous requestsenqueue

The asynchronous request invokes the EnQueue in RealCall, the Call implementation class

  • AsyncCall is an implementation class of Runnable.

    – the dispatcher (). The enqueue method

    The following conditions are met: 1. Asynchronous executionrunningAsyncCallsNumber < the maximum number of requestsmaxRequests; 2. Requests from each running hostrunningCallsForHost(call)< Maximum number of host requests to setmaxRequestsPerHost.

    If the conditions are met, AsyncCall is added to the asynchronous execution queuerunningAsyncCallsThe asynchronous request is then executed through the thread poolexecutorService().execute(call);

    If the conditions are not met, AsyncCall is added to the wait queuereadyAsyncCallsIn the.

    • ExecutorService () calls executorService().execute(call), because executorService() returns a thread pool (see below), you actually call the run method of each child thread (AsyncCall). – enter the executorService ()

      • Use the synchronized keyword to ensure that the executorService thread pool is a singleton.
      • This method returns a thread pool object executorService.
      • Parameters to ThreadPoolExecutor: Parameter 1: The number of core threads in the pool. A value of 0 indicates that all threads will be destroyed after a period of idle time. Parameter 2: Maximum number of threads, which can theoretically be extended indefinitely if set to the maximum value of the integer, but is actually limited by maxRequests(see above). Parameter 3: When the number of threads is greater than the number of core threads, the maximum lifetime of the extra idle threads is set to 60s.

      Enter the parent class NamedRunnable of AsyncCall

      – NamedRunnablerun()

      • The AsyncCallexecute()Implements thisexecute().

        Enter AsyncCallexecute()(1) associated
      • So why does it sayonFailureandonResponseIs executed in a child thread (hereexecute()In NamedRunnablerun()).

enqueueMethods to summarize

  • In 1, determining the current call refers to determining whether the current call has been executed only once (if(executed)).

The Dispatcher class

The main function is to maintain the request queue.

Summary – Asynchronous request flow



runningAsyncCalls
maxRequests
runningCallsForHost(call)
maxRequestsPerHost
runningAsyncCalls.add(call)
executorService().execute(call)



readyAsyncCalls
runningAsyncCalls
readyAsyncCalls
runningAsyncCalls

  • Q: When will the thread in the readyAsyncCalls queue be executed? See AsyncCallexecute()(Correlation 1), always executed in finallydispatcher().finished(this).

    – to enterdispatcher().finished(this)

    — enter 3 parametersfinished

    • Step 1: Invokecalls.remove(call)To remove asynchronous requests from the queue of asynchronous requests that are being executed.

      Step 2: InvokepromoteCalls(), adjust the task queue, because the thread is not safe, so addsynchronizedSynchronized code blocks;

      – to enterpromoteCalls()

      The operation is to traverse the asynchronous wait request queuereadyAsyncCalls.iterator()To remove the last requested task (i.remove()) and to the asynchronous execution queue (runningAsyncCalls.add(call)) and execute (execute(call)).

      Step 3: InvokerunningCallsCount(), recalculate the number of threads executing;

      – to enterrunningCallsCount()

      It returns the sum of asynchronous and synchronous requests being executed.