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、以及线程池大小。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。