Java线程池如何实现精准控制每秒API请求
作者:promise524
这篇文章主要介绍了Java线程池如何实现精准控制每秒API请求问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
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、以及线程池大小。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
