Java发起同步和异步HTTP请求
创始人
2025-05-29 05:19:41

同步与异步概念辨析

同步(synchronous)和异步(asynchronous)通常用于描述在执行操作时是否需要等待某个操作完成,以及如何处理返回结果

  • 类比生活
    • 同步是接力跑:前一个人跑完了再轮到下一个人跑
    • 异步是齐跑:大家在起跑线同时起跑
  • 编程
    • 同步编程(synchronous programming):大多数编程都是同步编程。在同步编程中,任务是按顺序执行的,一个任务必须等待另一个任务完成后才能开始执行
    • 异步编程(asynchronous programming):同时处理多个任务
  • 请求
    • 同步请求(synchronous request):每个请求都必须按顺序进行,并且程序必须等待每个请求完成后才能继续执行下一个请求
    • 异步请求(asynchronous request):同时发起多个请求

此处再提两个相关但不同的概念,并发(concurrency)和并行(parallelism)

  • 并发是指看起来貌似在同时执行多个任务(如时间片轮转),但在微观上他们都是按一定顺序被处理的,也可以算是某种意义上的“同时”、“异步”,看你怎么理解
  • 并行则是指多个任务执行就在同一时刻发生,算是真正意义上的“同时”、“异步”

Java 中的 HTTP 请求

对于 Java 中发起 HTTP 请求而言,一样有同步异步之分。看本文剩余部分之前首先需要学习用 Java 发起 HTTP 请求,对应后文的 getResponseContent() ,意为请求后获取响应内容,并在此篇博客文章中有介绍

💬相关

博客文章《Java发起HTTP请求并解析JSON返回数据》

https://blog.csdn.net/weixin_42077074/article/details/128672130

为了更好描述同步与异步,以下给出一个示例场景,我想发起 10 次 HTTP 请求,每次请求都带有参数开始时间 startTimeendTime,为 2023 年 1 月 1 日至 2023 年 1 月 10 日十天中每日零点和下一日的零点,如第一次请求的参数为 2023-01-01 00:00:002023-01-02 00:00:00

同步请求的实现

同步发请求无非就是直接调用或在 for 里调用 getResponseContent()

// 设置请求头
Map headers = new HashMap(){{// 设置接收内容类型put("Accept","application/json");// 设置发送内容类型put("Content-Type","application/json;charset=UTF-8");// 设置字符集put("charset", "UTF-8");// 设置访问者系统引擎版本、浏览器信息的字段信息,此处伪装成用户通过浏览器访问put("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
}};// 设置开始时间和结束时间
LocalDateTime startTime = LocalDateTime.of(2023, 1, 1, 0, 0, 0);
LocalDateTime endTime = LocalDateTime.of(2023, 1, 2, 0, 0, 0);// 创建一个数组来保存结果
String[] results = new String[10];for (int i = 0; i < 10; i++) {// 格式化开始时间和结束时间String formattedTime1 = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));String formattedTime2 = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));// 设置参数Map params = new HashMap(){{put("startTime", formattedTime1);put("endTime", formattedTime2);}};// 发送请求并获取响应results[i] = getResponseContent("http://www.example.com","GET", headers, params);// 更新开始时间和结束时间startTime = startTime.plusDays(i).plusSeconds(i);endTime = endTime.plusDays(i).plusSeconds(i);
}// 输出结果
for (int i = 0; i < 10; i++) {System.out.println(results[i]);
}

异步请求的实现

倘若请求量特别大,还按同步的方式进行,综合程序处理、网络延迟等因素,会非常地慢。

而对于异步而言,实现方式就比较多了,如 Java 11 中可以直接使用 java.net.http.HttpClient 类来创建异步 HTTP 客户端并使用 API,网上方法很多,此处不再赘述了

然而笔者处于兼容等各种考虑还是 Java8,Java8 并没有内置的异步 HTTP 客户端,要么调用第三方库来实现,如 Apache 的 HttpAsyncClient

org.apache.httpcomponentshttpasyncclient4.1.4

要么借助 Java 8 的标准库提供的基于 CompletableFuture 的异步编程来实现,笔者也是使用这个方案

注意, CompletableFuture 是并发而不是并行意义上的异步

// 创建 10 个异步任务
CompletableFuture[] futures = new CompletableFuture[10];
LocalDateTime startTime = LocalDateTime.of(2023, 1, 1, 0, 0, 0);
LocalDateTime endTime = LocalDateTime.of(2023, 1, 2, 0, 0, 0);for (int i = 0; i < 10; i++) {// 格式化开始时间和结束时间String formattedTime1 = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));String formattedTime2 = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));// 设置参数Map params = new HashMap(){{put("startTime", formattedTime1);put("endTime", formattedTime2);}};// 设置异步请求futures[i] = asyncHttpRequest("http://www.example.com","GET", headers, params);// 更新开始时间和结束时间startTime.plusDays(i).plusSeconds(i);endTime.plusDays(i).plusSeconds(i);
}// 等待异步任务完成,超时时间为5秒
try {CompletableFuture.allOf(futures).get(5, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {e.printStackTrace();
} catch (TimeoutException e) {System.out.println("请求超时");e.printStackTrace();return;
}// 输出每个异步任务的结果
for (int i = 0; i < 10; i++) {try {System.out.println(futures[i].get());} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}
}

其中的异步请求函数 asyncHttpRequest()

public static CompletableFuture asyncHttpRequest(String strURL, String method, Map headers, Map params) {return CompletableFuture.supplyAsync(() -> {try {return getResponseContent(strURL, method, headers, params);} catch (Exception e) {e.printStackTrace();return null;}});
}

相关内容

热门资讯

java 每日一练 (8) 文章目录1. 单选题2. 编程题 1. 单选题   1. 下列选项中关于 java 中 super ...
滁新高速淮南段发生一交通事故致... 本篇文章极速百科给大家谈谈滁新高速淮南段发生一交通事故致3人死亡,以及滁新高速淮南段拥堵对应的知识点...
快递投诉电话多少(极兔快递投诉... 今天给各位分享快递投诉电话多少的知识,其中也会对极兔快递投诉电话多少进行解释,如果能碰巧解决你现在面...
五羊本田小公主有几款?(五羊本... 本篇文章极速百科给大家谈谈五羊本田小公主有几款?,以及五羊本田小公主多少钱一台对应的知识点,希望对各...
红蓝buff是什么(红蓝buf... 本篇文章极速百科给大家谈谈红蓝buff是什么,以及红蓝buff是什么意思网络用语对应的知识点,希望对...
Gitee搭建个人博客(Bea... 目录一、引言二、博客模板选型 - Jekyll三、安装Jekyll环境3.1 安装Ruby3.2 安...
记一次磁盘扩容 起因 在使用firefly板子时,刷完固件发现根目录竟然只有3G,根本没...
开车撞死人怎么处理与赔偿?撞死... 今天给各位分享开车撞死人怎么处理与赔偿?撞死人协商最佳时间的知识,其中也会对开车撞死人要赔偿多少钱进...
ulzzang是什么牌子(ul... 本篇文章极速百科给大家谈谈ulzzang是什么牌子,以及ulzzang是什么牌子鞋对应的知识点,希望...
中国各重点城市豪车数量排名:北... 今天给各位分享中国各重点城市豪车数量排名:北上深广包揽前四!的知识,其中也会对中国地区豪车排行榜进行...
大分辨率数据集切割 前言:对于航拍、遥感影像数据集而言,此类数据集包含较多目标,...
叠信纸的四种方法(叠信纸的四种... 本篇文章极速百科给大家谈谈叠信纸的四种方法,以及叠信纸的四种方法a4多张图片对应的知识点,希望对各位...
记录Quartz在项目中的使用... 黑马传智健康项目中遇到的技术,感觉这个解决思路挺新颖的,就记录下来了。用...
Opengauss CLOG模... 上篇讲解了opengauss CLOG模块分区优化原理篇,本文将从源代码实现层面讨论具...
广汽三菱放大招2021款奕歌燃... 今天给各位分享广汽三菱放大招2021款奕歌燃情版上市售价16.78万元的知识,其中也会对广汽三菱弈歌...
科斯沃斯引擎(科斯沃d037)... 今天给各位分享科斯沃斯引擎的知识,其中也会对科斯沃d037进行解释,如果能碰巧解决你现在面临的问题,...
展望过去,想象未来,瑞航360... 今天给各位分享展望过去,想象未来,瑞航360全景2018新征程的知识,其中也会对瑞航lx188机型进...
考研数二第四讲 分段函数的复合... 分段函数的复合函数求分段函数的复合函数,这是考研高数中的一个重要考点。专升本的高数不考...
7座MPV车型推荐,7座MPV... 本篇文章极速百科给大家谈谈7座MPV车型推荐,7座MPV车型大全,以及7座mpv汽车大全2020对应...
支付宝怎么取消自动续费(苹果手... 今天给各位分享支付宝怎么取消自动续费的知识,其中也会对苹果手机支付宝怎么取消自动续费进行解释,如果能...
TH是什么意思(Things是... 本篇文章极速百科给大家谈谈TH是什么意思,以及Things是什么意思翻译对应的知识点,希望对各位有所...
上汽大众途观怎么样(上汽大众途... 本篇文章极速百科给大家谈谈上汽大众途观怎么样,以及上汽大众途观l2022版质量对应的知识点,希望对各...
solidworks转urdf... 是用solidworks成功导出了一次urdf,记录一下导出时各参数的说明。 基座的...
如何买火车票网上订票?网上买火... 今天给各位分享如何买火车票网上订票?网上买火车票怎么买的知识,其中也会对怎样买网上火车票进行解释,如...
加美机油质量怎么样?加美润滑油... 本篇文章极速百科给大家谈谈加美机油质量怎么样?加美润滑油排名第几,以及加美机油咋样对应的知识点,希望...
哈弗E2012款基本型配置-参... 今天给各位分享哈弗E2012款基本型配置-参数配置详解的知识,其中也会对哈弗二多少钱进行解释,如果能...
买拉法要满足什么条件(购买拉法... 今天给各位分享买拉法要满足什么条件的知识,其中也会对购买拉法的几条要求进行解释,如果能碰巧解决你现在...
JAVA并发编程之锁 1、乐观锁和悲观锁 1.1、悲观锁 认为自己在使用数据的时候一定有别的线程来修改数据,...
mysql数据库提权 0x00数据库帐号密码获取方式数据库帐号密码获取方式:1.网站存在高权限SQL注入点2...
橱窗男孩蔚来(橱窗小男孩看车壁... 今天给各位分享橱窗男孩蔚来的知识,其中也会对橱窗小男孩看车壁纸蔚来进行解释,如果能碰巧解决你现在面临...