java中基于线程池实现指定每秒发送一定数量的api请求,可以使用scheduledexecutorservice来调度任务,同时使用threadpoolexecutor来处理并发请求,可以根据实际需求调整每秒请求数量、执行时间、以及线程池大小。
实现思路
1.创建线程池
- 使用
executors.newscheduledthreadpool()
来创建一个调度线程池 - 并使用
executors.newfixedthreadpool()
来创建一个用于发送api请求的线程池
2.调度任务
- 使用
scheduledexecutorservice
来按固定速率调度任务。 - 通过控制任务的频率,可以确保每秒发送指定数量的请求。
3.定义api请求任务
- 定义一个实现
runnable
接口的类 - 负责执行具体的api请求
4.控制请求速率
- 使用调度器每秒提交指定数量的任务到线程池中执行。
引入依赖
<!-- apache httpclient --> <dependency> <groupid>org.apache.httpcomponents.client5</groupid> <artifactid>httpclient5</artifactid> <version>5.2</version> </dependency>
实现代码
import org.apache.hc.client5.http.classic.methods.httpget; import org.apache.hc.client5.http.classic.methods.httpurirequestbase; import org.apache.hc.client5.http.impl.classic.closeablehttpclient; import org.apache.hc.client5.http.impl.classic.closeablehttpresponse; import org.apache.hc.client5.http.impl.classic.httpclients; import org.apache.hc.core5.http.parseexception; import org.apache.hc.core5.http.io.entity.entityutils; import java.io.ioexception; import java.util.concurrent.*; import java.util.concurrent.atomic.atomicinteger; public class apirequestscheduler { // 定义线程池,用于并发发送api请求 private final executorservice requestexecutor; // 定义调度线程池,用于定时调度请求任务 private final scheduledexecutorservice scheduler; // 记录已发送的请求数量 private final atomicinteger requestcounter; // 每秒发送的请求数量 private final int requestspersecond; // apache httpclient 实例 private final closeablehttpclient httpclient; // api 请求的目标url private final string apiurl; // 构造函数,初始化线程池和调度器 public apirequestscheduler(int requestspersecond, string apiurl) { this.requestspersecond = requestspersecond; this.requestexecutor = executors.newfixedthreadpool(requestspersecond); this.scheduler = executors.newscheduledthreadpool(1); this.requestcounter = new atomicinteger(0); this.httpclient = httpclients.createdefault(); this.apiurl = apiurl; } // 开始调度api请求任务 public void start() { // 每秒调度任务,按照每秒发送的请求数量来执行 scheduler.scheduleatfixedrate(() -> { for (int i = 0; i < requestspersecond; i++) { requestexecutor.submit(this::sendapirequest); } }, 0, 1, timeunit.seconds); } // 停止调度和关闭线程池及httpclient public void stop() { scheduler.shutdown(); requestexecutor.shutdown(); try { if (!scheduler.awaittermination(1, timeunit.seconds)) { scheduler.shutdownnow(); } if (!requestexecutor.awaittermination(1, timeunit.seconds)) { requestexecutor.shutdownnow(); } httpclient.close(); } catch (interruptedexception | ioexception e) { scheduler.shutdownnow(); requestexecutor.shutdownnow(); try { httpclient.close(); } catch (ioexception ioexception) { ioexception.printstacktrace(); } } } // 使用apache httpclient发送api请求 private void sendapirequest() { int requestid = requestcounter.incrementandget(); httpurirequestbase request = new httpget(apiurl); system.out.println("sending api request #" + requestid); try (closeablehttpresponse response = httpclient.execute(request)) { string responsebody = entityutils.tostring(response.getentity()); system.out.println("request #" + requestid + " completed with status: " + response.getcode() + ", response: " + responsebody); } catch (ioexception | parseexception e) { system.err.println("request #" + requestid + " failed: " + e.getmessage()); } } public static void main(string[] args) { // 每秒发送5个api请求,目标url为http://example.com/api apirequestscheduler scheduler = new apirequestscheduler(5, "http://www.dzy.com/api"); // 启动调度器 scheduler.start(); // 运行10秒后停止调度器 try { thread.sleep(10000); } catch (interruptedexception e) { thread.currentthread().interrupt(); } // 停止调度器 scheduler.stop(); } }
实现效果
每秒发送指定数量的api请求,使用apache httpclient处理http通信,并确保在多线程环境中正确管理资源。
可以根据实际需求调整每秒请求数量、api url、以及线程池大小。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论