Java使用HttpURLConnection并行发送多个GET API请求方案咨询
该场景最优实现方案
核心采用带并发数控制的线程池实现批量并行请求,既可以大幅降低总耗时,也能避免无限制发起请求导致本地资源耗尽、触发下游API限流封禁的问题。
实现注意要点
- 原有代码里的
Authenticator.setDefault()是全局配置,仅需在程序初始化时执行一次,不要放在单次请求逻辑中重复调用 - 必须给每个请求加连接超时、读取超时配置,避免单个请求卡住占用线程资源
- 每个请求单独做异常捕获,单个请求失败不影响整体任务执行
- 并发线程数根据下游API的限流规则调整,常规场景下设置为10~50即可,IO密集型任务不需要和CPU核心数绑定
代码实现示例
首先把单次请求逻辑封装为Callable任务:
import java.net.HttpURLConnection; import java.net.URL; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.concurrent.Callable; import org.json.JSONObject; public class ApiRequestTask implements Callable<JSONObject> { private final String variable; private final String user; private final String password; // 构造方法传入变量、鉴权信息 public ApiRequestTask(String variable, String user, String password) { this.variable = variable; this.user = user; this.password = password; } @Override public JSONObject call() throws Exception { String url = "https://my/api" + variable + "test"; URL _url = new URL(url); HttpURLConnection con = (HttpURLConnection) _url.openConnection(); // 配置超时,避免卡住 con.setConnectTimeout(5000); con.setReadTimeout(10000); con.setRequestMethod("GET"); con.setRequestProperty("Accept", "application/json"); try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) { String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } return new JSONObject(response.toString()); } finally { con.disconnect(); } } }
主逻辑实现并行提交和结果收集:
import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.net.Authenticator; import java.net.PasswordAuthentication; import org.json.JSONObject; public class BatchApiRequest { public static void main(String[] args) { String user = "your_username"; String password = "your_password"; // 全局仅设置一次鉴权 Authenticator.setDefault(new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(user, password.toCharArray()); } }); // 你的2000个变量的列表 List<String> variableList = new ArrayList<>(); // 自行填充variableList的内容 // 固定并发数的线程池,并发数根据实际情况调整,这里示例设为20 ExecutorService executor = Executors.newFixedThreadPool(20); List<Future<JSONObject>> futureList = new ArrayList<>(); // 提交所有请求任务 for (String var : variableList) { futureList.add(executor.submit(new ApiRequestTask(var, user, password))); } // 收集所有结果 List<JSONObject> resultList = new ArrayList<>(); for (Future<JSONObject> future : futureList) { try { resultList.add(future.get()); } catch (Exception e) { // 单个请求异常处理,比如打印日志、记录失败的变量 e.printStackTrace(); } } // 关闭线程池 executor.shutdown(); } }
可选优化方案
如果对性能有更高要求,可以把原生的HttpURLConnection替换为OkHttp、Apache HttpClient这类成熟的HTTP客户端,内置连接池可以复用TCP连接,减少频繁握手的开销,并行请求的性能会更好。
内容的提问来源于stack exchange,提问作者user0204
相关产品推荐
相关产品推荐

