当前位置: 首页 > news >正文

嘉兴网站建设公司电话优秀seo平台

嘉兴网站建设公司电话,优秀seo平台,网站建设管理工作经验介绍,门头沟石家庄网站建设OkHttp是当下Android使用最频繁的网络请求框架#xff0c;由Square公司开源。Google在Android4.4以后开始将源码中 的HttpURLConnection底层实现替换为OKHttp#xff0c;同时现在流行的Retrofit框架底层同样是使用OKHttp的。 OKHttp优点: 1、支持Http1、Http2、Quic以及Web…OkHttp是当下Android使用最频繁的网络请求框架由Square公司开源。Google在Android4.4以后开始将源码中 的HttpURLConnection底层实现替换为OKHttp同时现在流行的Retrofit框架底层同样是使用OKHttp的。 OKHttp优点: 1、支持Http1、Http2、Quic以及WebSocket 2、连接池复用底层TCP(Socket)减少请求延时 3、无缝的支持GZIP减少数据流量 4、缓存响应数据减少重复的网络请求 5、请求失败自动重试主机的其他ip自动重定向 OKHttp调用流程 OkHttp请求过程中最少只需要接触OkHttpClient、Request、Call、 Response但是框架内部进行大量的逻辑处理。 所有的逻辑大部分集中在拦截器中但是在进入拦截器之前还需要依靠 分发器来调配请求任务。 分发器内部维护队列与线程池完成请求调配 拦截器五大默认拦截器完成整个请求过程。 用户是不需要直接操作任务分发器的获得的 RealCall 中就分别提供了 execute 与 enqueue 来开始同步请求或异步请求。无论是同步还是异步请求实际上真正执行请求的工作都在 getResponseWithInterceptorChain() 中。这个 方法就是整个OkHttp的核心拦截器责任链。 Override public Response execute() throws IOException {synchronized (this) {if (executed) throw new IllegalStateException(Already Executed);executed true;}captureCallStackTrace();eventListener.callStart(this);try {//调用分发器client.dispatcher().executed(this);//执行请求Response result getResponseWithInterceptorChain();if (result null) throw new IOException(Canceled);return result;} catch (IOException e) {eventListener.callFailed(this, e);throw e;} finally {//请求完成client.dispatcher().finished(this);} } 分发器异步请求工作流程 Dispatcher 分发器就是来调配请求任务的内部会包含一个线程池。可以在创建 OkHttpClient 时传递我们 自己定义的线程池来创建分发器。 Dispatcher中的成员有:  //异步请求同时存在的最大请求 private int maxRequests 64; //异步请求同一域名同时存在的最大请求 private int maxRequestsPerHost 5; //闲置任务(没有请求时可执行一些任务由使用者设置) private Nullable Runnable idleCallback; //异步请求使用的线程池 private Nullable ExecutorService executorService; //异步请求等待执行队列 private final DequeAsyncCall readyAsyncCalls new ArrayDeque(); //异步请求正在执行队列 private final DequeAsyncCall runningAsyncCalls new ArrayDeque(); //同步请求正在执行队列 private final DequeRealCall runningSyncCalls new ArrayDeque(); 同步请求 synchronized void executed(RealCall call) {runningSyncCalls.add(call); } 因为同步请求不需要线程池也不存在任何限制。所以分发器仅做一下记录。 异步请求 synchronized void enqueue(AsyncCall call) {if (runningAsyncCalls.size() maxRequests runningCallsForHost(call) maxRequestsPerHost) {runningAsyncCalls.add(call);executorService().execute(call);} else {readyAsyncCalls.add(call);} } 当正在执行的任务未超过最大限制64同时 runningCallsForHost(call) maxRequestsPerHost 同一Host的请求 不超过5个则会添加到正在执行队列同时提交给线程池。否则先加入等待队列。 加入线程池直接执行如果加入等待队列后就需要等待有空闲名额才开始执行。因此每次执行完 一个请求后都会调用分发器的 finished 方法 //异步请求调用void finished(AsyncCall call) {finished(runningAsyncCalls, call, true);}//同步请求调用void finished(RealCall call) {finished(runningSyncCalls, call, false);}private T void finished(DequeT calls, T call, boolean promoteCalls) {int runningCallsCount;Runnable idleCallback;synchronized (this) {//不管异步还是同步执行完后都要从队列移除(runningSyncCalls/runningAsyncCalls)if (!calls.remove(call)) throw new AssertionError(Call wasnt in-flight!);if (promoteCalls) promoteCalls();//异步任务和同步任务正在执行的和runningCallsCount runningCallsCount();idleCallback this.idleCallback;}// 没有任务执行执行闲置任务if (runningCallsCount 0 idleCallback ! null) {idleCallback.run();}} 需要注意的是 只有异步任务才会存在限制与等待所以在执行完了移除正在执行队列中的元素后异步任务结束会 执行 promoteCalls() 。很显然这个方法肯定会重新调配请求。 private void promoteCalls() {//如果任务满了直接返回if (runningAsyncCalls.size() maxRequests) return;//没有等待执行的任务返回if (readyAsyncCalls.isEmpty()) return;//遍历等待执行队列for (IteratorAsyncCall i readyAsyncCalls.iterator(); i.hasNext(); ) {AsyncCall call i.next();//等待任务想要执行还需要满足这个等待任务请求的Host不能已经存在5个了if (runningCallsForHost(call) maxRequestsPerHost) {i.remove();runningAsyncCalls.add(call);executorService().execute(call);}if (runningAsyncCalls.size() maxRequests) return; // Reached max capacity.}} 在满足条件下会把等待队列中的任务移动到 runningAsyncCalls 并交给线程池执行。所以分发器到这里就完了。 逻辑上还是非常简单的。 分发器线程池 分发器就是来调配请求任务的内部会包含一个线程池。当异步请求时会将请求任务交给线程池 来执行。那分发器中默认的线程池是如何定义的呢为什么要这么定义 public synchronized ExecutorService executorService() {if (executorService null) {executorService new ThreadPoolExecutor(0, //核心线程Integer.MAX_VALUE, //最大线程60, //空闲线程闲置时间TimeUnit.SECONDS, //闲置时间单位new SynchronousQueueRunnable(), //线程等待队列Util.threadFactory(OkHttp Dispatcher, false) //线程创建工厂);}return executorService;} 在OkHttp的分发器中的线程池定义如上其实就和 Executors.newCachedThreadPool() 创建的线程一样。首先核 心线程为0表示线程池不会一直为我们缓存线程线程池中所有线程都是在60s内没有工作就会被回收。 而最大线 程 Integer.MAX_VALUE 与等待队列 SynchronousQueue 的组合能够得到最大的吞吐量。即当需要线程池执行任务 时如果不存在空闲线程不需要等待马上新建线程执行任务等待队列的不同指定了线程池的不同排队机制。 一般来说等待队列 BlockingQueue 有 ArrayBlockingQueue 、 LinkedBlockingQueue 与 SynchronousQueue 。 假设向线程池提交任务时核心线程都被占用的情况下 ArrayBlockingQueue 基于数组的阻塞队列初始化需要指定固定大小。 当使用此队列时向线程池提交任务会首先加入到等待队列中当等待队列满了之后再次提交任务尝试加入 队列就会失败这时就会检查如果当前线程池中的线程数未达到最大线程则会新建线程执行新提交的任务。所以 最终可能出现后提交的任务先执行而先提交的任务一直在等待。 LinkedBlockingQueue 基于链表实现的阻塞队列初始化可以指定大小也可以不指定。 当指定大小后行为就和 ArrayBlockingQueu 一致。而如果未指定大小则会使用默认的 Integer.MAX_VALUE 作 为队列大小。这时候就会出现线程池的最大线程数参数无用因为无论如何向线程池提交任务加入等待队列都会 成功。最终意味着所有任务都是在核心线程执行。如果核心线程一直被占那就一直等待。 SynchronousQueue : 无容量的队列。 使用此队列意味着希望获得最大并发量。因为无论如何向线程池提交任务往队列提交任务都会失败。而失败后 如果没有空闲的非核心线程就会检查如果当前线程池中的线程数未达到最大线程则会新建线程执行新提交的任 务。完全没有任何等待唯一制约它的就是最大线程数的个数。因此一般配合 Integer.MAX_VALUE 就实现了真正的 无等待。 但是需要注意的时我们都知道进程的内存是存在限制的而每一个线程都需要分配一定的内存。所以线程并不 能无限个数。那么当设置最大线程数为 Integer.MAX_VALUE 时OkHttp同时还有最大请求任务执行个数: 64的限制。这样即解决了这个问题同时也能获得最大吞吐。
http://www.w-s-a.com/news/898938/

相关文章:

  • 交通局网站建设方案答辩ppt模板免费下载 素材
  • 个人摄影网站推介网手机版
  • 有哪些免费的视频网站网站开发和竞价
  • 学校网站如何做广州商城型网站建设
  • 微网站建设哪家便宜易优建站系统
  • 推荐做木工的视频网站毕业设计做的网站抄袭
  • 网站导航页面制作wordpress调用文章阅读量
  • app小程序网站开发品牌购物网站十大排名
  • 用wordpress做购物网站龙岩品牌设计
  • 网站开发是指wordpress系统在线升级
  • 网站建设运营的灵魂是什么意思页面跳转中
  • 家政服务网站源码重庆建网站企业有哪些
  • 怎样分析一个网站做的好坏重庆长寿网站设计公司哪家专业
  • 百度助手app下载苏州seo关键词优化排名
  • 17网站一起做 佛山诸城网站建设多少钱
  • 郑州网站建设培训学校泉州做网站设计公司
  • 西峡做网站深圳建筑工务署官网
  • 单县网站惠州seo计费
  • 万网网站建设 优帮云怎样用记事本做网站
  • 注册域名后网站建设百度指数的功能
  • 怎么做伪静态网站山西网站建设设计
  • 做小型企业网站多少钱衡阳市建设局网站
  • 金华专业网站建设公司网站建设空间和服务器方式
  • 自己做的网站在浏览器上显示不安全吗wordpress revolution slider
  • 西安网站建设推广优化搜索引擎营销
  • 互联网站备案管理工作方案 工信部注册深圳公司需要什么条件
  • 网站网站服务器网站建设 物流
  • 国外开发网站手机网站建设制作
  • 怎么把自己做的网站传网上青岛工程建设监理公司网站
  • 网站301跳转效果商丘网站公司