范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

HttpClient的异步调用,你造吗?

  一、前言
  HttpClient提供了两种I/O模型:经典的java阻塞I/O模型和基于Java NIO的异步非阻塞事件驱动I/O模型。
  Java中的阻塞I/O是一种高效、便捷的I/O模型,非常适合并发连接数量相对适中的高性能应用程序。只要并发连接的数量在1000个以下并且连接大多忙于传输数据,阻塞I/O模型就可以提供最佳的数据吞吐量性能。然而,对于连接大部分时间保持空闲的应用程序,上下文切换的开销可能会变得很大,这时非阻塞I/O模型可能会提供更好的替代方案。
  异步I/O模型可能更适合于比较看重资源高效利用、系统可伸缩性、以及可以同时支持更多HTTP连接的场景。 二、HttpClient中的Future
  在HttpClient官网Tutorial的高级话题中,我们可以发现其提供了用于异步执行的FutureRequestExecutionService服务类。
  使用FutureRequestExecutionService,允许我们发起http调用后,调用函数马上返回(调用线程不会阻塞等到相应结果返回)一个Future对象,然后调用线程可以在需要响应结果的地方调用Future对象的get方法来阻塞等待结果。
  使用FutureRequestExecutionService的优点是,我们可以使用多个线程并发调度请求、设置任务超时,或者在不再需要响应时取消它们。
  FutureRequestExecutionService其实是用一个HttpRequestFutureTask包装请求,该HttpRequestFutureTask扩展了JDK中的FutureTask。这个类允许我们取消任务、跟踪各种执行指标,如请求持续时间等。
  下面我们看一个例子:  // 1.创建线程池  private static ExecutorService executorService = Executors.newFixedThreadPool(5);   // 2.创建http回调函数  private static final class OkidokiHandler implements ResponseHandler {   public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {    // 2.1处理响应结果    return EntityUtils.toString(response.getEntity());   }  }   public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {   // 3.创建httpclient对象   CloseableHttpClient httpclient = HttpClients.createDefault();    // 4.创建FutureRequestExecutionService实例   FutureRequestExecutionService futureRequestExecutionService = new FutureRequestExecutionService(httpclient,     executorService);    // 5.发起调用   try {    // 5.1请求参数    HttpGet httpget1 = new HttpGet("http://127.0.0.1:8080/test1");    HttpGet httpget2 = new HttpGet("http://127.0.0.1:8080/test2");    // 5.2发起请求,不阻塞,马上返回    HttpRequestFutureTask task1 = futureRequestExecutionService.execute(httpget1,      HttpClientContext.create(), new OkidokiHandler());     HttpRequestFutureTask task2 = futureRequestExecutionService.execute(httpget2,      HttpClientContext.create(), new OkidokiHandler());     // 5.3 do somthing     // 5.4阻塞获取结果    String str1 = task1.get();    String str2 = task2.get();    System.out.println("response:" + str1 + " " + str2);   } finally {    httpclient.close();   }  }
  如上代码1创建了一个线程池用来作为http异步执行的后台线程,代码2创建了一个http响应结果处理器,用来异步处理http的响应结果。
  代码3创建了一个HttpClient对象,代码4创建一个FutureRequestExecutionService,参数1为创建的httpclient对象,参数2为创建的线程池。
  代码5则创建2个Get请求参数,然后执行代码5.2发起两个http请求,该调用会马上返回自己对于的HttpRequestFutureTask对象,调用线程也会马上返回,然后调用线程就可以在5.3做其他的事情,最后在需要获取http响应结果的地方,比如代码5.4调用两个future的get()方法来获取结果。
  如上基于Future方式,我们可以并发的发起两个http请求,而之前阻塞方式,则是顺序执行的。
  但是基于上面Future方式,我们调用线程还是会在代码5.4阻塞等待响应结果,这并不是我们想要的,我们想要的是事件通知,http确实也提供了注册CallBack的方式。
  首先我们需要实现FutureCallback接口,用来接收通知: private static final class MyCallback implements FutureCallback {    public void failed(final Exception ex) {    System.out.println(ex.getLocalizedMessage());   }    public void completed(final String result) {    System.out.println(result);   }    public void cancelled() {    System.out.println("cancelled");   }  }
  然后我们只需要修改代码5.2,使用三个参数的execute方法发起调用:  // 5.发起调用   try {    // 5.1请求参数    HttpGet httpget1 = new HttpGet("http://127.0.0.1:8080/test1");    HttpGet httpget2 = new HttpGet("http://127.0.0.1:8080/test2");    // 5.2发起请求,不阻塞,马上返回    HttpRequestFutureTask task1 = futureRequestExecutionService.execute(httpget1,      HttpClientContext.create(), new OkidokiHandler(), new MyCallback());     HttpRequestFutureTask task2 = futureRequestExecutionService.execute(httpget2,      HttpClientContext.create(), new OkidokiHandler(), new MyCallback());               //main线程休眠10s,避免请求结束前,关闭了链接    Thread.sleep(10000); ...
  如上代码,使用CallBack后,调用线程就得到了彻底解放,就不必再阻塞获取结果了,当http返回结果后,会自动调用我们注册的CallBack。
  三、HttpAsyncClient-真正的异步
  上面HttpClient提供的CallBack的方式,虽然解放了调用线程,但是并不是真正意义上的异步调用,因为其异步调用的支持是基于我们创建的executorService线程。即:虽然发起http调用后,调用线程马上返回了,但是其内部还是使用executorService中的一个线程阻塞等待响应结果。
  HttpAsyncClient则使用Java NIO的异步非阻塞事件驱动I/O模型,实现了真正意义的异步调用,使用HttpAsyncClient我们需要引入其专门的 包:    org.apache.httpcomponents   httpasyncclient   4.1.4 
  然后改造后代码如下: // 1.创建CallBack  private static final class MyCallback implements FutureCallback {    public void failed(final Exception ex) {    System.out.println(ex.getLocalizedMessage());   }    public void completed(final HttpResponse response) {    try {     System.out.println(EntityUtils.toString(response.getEntity()));    } catch (ParseException e) {     e.printStackTrace();    } catch (IOException e) {     e.printStackTrace();    }   }    public void cancelled() {    System.out.println("cancelled");   }  }   public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {   // 2.创建异步httpclient对象   CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom().build();    // 3.发起调用   try {     // 3.0启动    httpclient.start();    // 3.1请求参数    HttpGet httpget1 = new HttpGet("http://127.0.0.1:8080/test1");    HttpGet httpget2 = new HttpGet("http://127.0.0.1:8080/test2");    // 3.2发起请求,不阻塞,马上返回    httpclient.execute(httpget1, new MyCallback());    httpclient.execute(httpget2, new MyCallback());     // 3.3休眠10s,避免请求执行完成前,关闭了链接    Thread.sleep(10000);   } finally {    httpclient.close();   }  }
  如上代码1,创建异步回调实现,用于处理Http响应结果。代码2创建了异步HttpClient,代码3.0启动client,代码3.2发起请求。
  基于Java NIO的异步,当发起请求后,调用方不会使用任何线程同步等待http服务端的响应结果(少量的NIO线程不算哦,因为其个数固定,并且不随并发请求数量变化),而是会使用少量内存来记录请求信息,以便服务端响应结果回来后,可以找到对应的回调函数进行执行。 四、总结
  本文概要讲解了Http的异步调用,关于更多Java中异步调用与异步执行的知识,可以参考Java异步编程实战这本书

挑战洛希极限?科学家在不可能的地方发现行星环新华社北京2月10日电一支国际天文研究团队发现太阳系边缘一颗名为创神星的小行星拥有一个行星环,而这个行星环的存在挑战现有认知。依据天文学界目前普遍接受并应用的洛希极限推论,那个位置苹果AppleMusic存在问题支持空间音频的歌曲需通过桌面端同步IT之家2月10日消息,国外科技媒体MacWorld在最新文章中指出了AppleMusic服务存在的一个问题支持空间音频的歌曲需要通过桌面设备进行同步。文章编辑达里尔巴克斯特(Da速递丨无锡出台全国首部车联网发展地方性法规头条无锡出台全国首部车联网发展地方性法规日前,无锡市车联网发展促进条例正式颁布,将于3月1日起施行。这是国内首部推动车联网发展的地方性法规,其首次将车路协同基础设施纳入道路建设工程中国空间站全面建成后航天员首次成功出舱人民日报作者刘诗瑶余建斌在北京航天飞行控制中心拍摄的费俊龙成功出舱后挥手致意的画面。费俊龙打开问天实验舱气闸舱出舱舱门。费俊龙开展舱外操作。张陆结束出舱任务正在返回。图片均为新华社宝山有个地方宝山,自古人文荟萃,人杰地灵。作为一个忙碌的都市人,我们每天行色匆匆,路过一条条街道,一栋栋楼房或许您会留意到有些路名似曾相识,或是觉得某栋建筑别具风采,但您也许没有时间停下脚步,颜值与演技都在线,浮图缘中的4位女演员,你最喜欢哪一个?四个不同身份的女人,四种完全不同的命运,看完浮图缘,才明白人间清醒终有一归。皇权可以得天下,却难得到爱人心,即使锦衣玉食,内心的荒凉依然无处安放,可悲的是命运,可叹的是人性。4位女步步惊心十福晋整容大变样!曾与张檬大战,如今转型当制片人刘雨欣有网友在看到曾经在步步惊心中饰演娇俏可爱的明玉格格,也就是十福晋的演员刘雨欣,在某个社交平台上发布了一组照片。该组照片中,刘雨欣和不少有名的好莱坞亚裔明星站在一起,像约翰赵奥江映蓉都是全国冠军,为什么我就没有李宇春红?提起超女,很多人的第一反应就是李宇春,曾轶可。再者就是张靓颖,何洁。对于后续几届超女,知之甚少。类似于李霄云,苏妙玲这样的歌手,更是在跨年晚会上才会注意到。其实在2009年的快乐女胡蝶民国第一美女她是整个民国时期最著名的影后,跨越整个默片时代与有声片时代,她有民国第一美女之称。1931年,她首度加冕电影皇后。此后更在两年之内三度评选中均被选为影后。甚至到了数十年后,年过半百大众为何原谅李小璐不原谅董洁?因为比说谎更可恶的是霸凌潘粤明和董洁的关系成谜,近日来一再反转并产生悬念2月5日,潘粤明为儿子顶顶送上生日祝福,并艾特了前妻董洁。隔空送祝福是潘粤明每年的常规操作,本不该引起轰动,可董洁竟然转发评论了他一中国元素救不了,法国人哭了法国最近有一部电影上映,巴黎各地铁站张贴着宣传海报。这便是大名鼎鼎的阿斯泰利克斯历险记系列。阿斯泰利克斯历险记,法语Astrix,又译高卢英雄传,在法国是家喻户晓的动漫人物。原作漫
鉴赏LGHU915QEG实现亮度色彩与HDR性能飞跃激光电视或者说激光超短焦投影机的出现,让沉闷的客厅大屏市场掀起了不少的波澜,巧妙地解决了如何将源于高端商业影院中的激光放映技术,引入到庞大的客厅大屏市场中的难题,让普通用户也可以在光遇圣诞节新礼包,两个旗帜加排球,售价或需98元?光遇圣诞节新礼包,两个旗帜加排球,售价或需98元?前言大家好,我是林克。每日分享游戏电竞情报攻略玩法等。接到粉丝投稿,说她在某音上,看到一个UP主,发布了关于宴会节(也就是圣诞节)中国女排还有希望03负于意大利队后(附国际排联官网数据)中国女排还有希望03负于意大利队之后(附国际排联官网数据)本届世界锦标赛中国队再负一场,以03(242616252025)负于意大利队,目前还没有完成十六进八的任务。比赛虽然输了,长沙国际车展12月启幕突出智能化电动化和网联化智能黑科技亮相长沙国际车展(资料图)。龚倩摄中新网长沙10月8日电(龚倩)第十八届中国(长沙)国际汽车博览会(以下简称长沙国际车展)将于12月7日至12日在长沙国际会展中心举行。电骑行知识一些国际通用的骑行手势,你知道哪些吗一些国际通用的骑行手势,你知道哪些1。右手在肩上高举摆动表示队伍出发,左手同义2。右手高举握拳表示前方出现红灯或者紧急事故,需要立刻停止前进,左手同义3。右手手掌向地面摆动提示前方这支队伍被国际篮联称赞实力强大,比赛毫无悬念中国三人女篮U23国家队在6日进行的世界杯比赛中以217大胜以色列队,国际篮联在其官网上对中国队大加赞扬。官网文章开头称在罗马尼亚布加勒斯特举行的三人篮球U23世界杯第二天的比赛中阿里巴巴国际站效果不好该如何优化总结一下现在有些做国际站的商家问题1。询盘少2。没大客户成交少3。品牌广告效果差以上就是现在一些国际站商家的问题,今天就给大家一个优化建议,有些长,大家耐心看完。1。首先针对询盘少每日一味抗癌中药丁香,功效温中降逆散寒止痛温肾助阳丁香桃金娘科常绿乔木植物丁香的花蕾。主产于坦桑尼亚马来西亚印度尼西亚,我国海南省也有栽培。通常于9月至次年3月开花,花蕾由绿转红时采收,晒干,生用。别名公丁香。性味辛,温。归经脾经秋季国产新品争奇斗艳!98寸电视占主流,哪个品牌更值得选?随着大家生活质量的不断提高,电视机行业可谓越来越卷。特别是近几年来家庭影院的普及,大尺寸电视机尤其是98寸电视机备受追捧。在今年秋季新品中,TCL海信创维长虹等品牌都升级各自新品。拒绝牙结石,素诺冲洗一体智能可视洁牙仪说到牙齿养护,大家第一反应肯定是刷牙,良好的清洁习惯能够很好地延长牙齿的寿命。而今年轻人更多的是选择电动牙刷来更进一步的清洁牙齿,但随着生活条件的改变,人们接触到事物的种类愈发丰富TCL7999元电视不输海信万元旗舰?内行人道出真相技术是底气2022年上半年,TCL的全球电视销量份额占比11。1,排名世界第三而海信也获得了不错的成绩,占比9。5,居TCL之后。对于国内电视的排名,很明显可以看到近几年TCL一直稳居一哥之