Optimizing Multiple Interface Calls with Asynchronous Execution in Java
To reduce response time when invoking multiple independent APIs, this article demonstrates how to refactor sequential Java calls into asynchronous executions using thread pools and CompletableFuture, providing complete code examples and performance comparisons.
As business logic grows and data volumes increase, some interfaces become slow, prompting the need for performance optimization. This article introduces an asynchronous approach to call multiple independent interfaces in parallel, thereby reducing overall response time.
Applicable Conditions
Multiple independent interfaces with no mutual dependencies.
The longest‑running interface accounts for a large portion of total latency.
Before Optimization – Sequential Calls
The original code calls each interface one after another:
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DemoTest {
public static void main(String[] args) throws Exception {
long beginTime = System.currentTimeMillis();
int processA = new InterfaceA().process();
int processB = new InterfaceB().process();
int result = processA + processB;
log.info("执行结果:{} 耗时:{}", result, System.currentTimeMillis() - beginTime);
}
@Slf4j
public static final class InterfaceA {
Integer result = 1;
public int process() {
long beginTime = System.currentTimeMillis();
try { Thread.sleep(2000); } catch (Exception e) { log.error("InterfaceA.process Exception"); }
log.info("执行接口InterfaceA.process 耗时:{}ms", System.currentTimeMillis() - beginTime);
return result;
}
}
@Slf4j
public static final class InterfaceB {
Integer result = 1;
public int process() {
long beginTime = System.currentTimeMillis();
try { Thread.sleep(2000); } catch (Exception e) { log.error("InterfaceB.process Exception"); }
log.info("执行接口InterfaceB.process 耗时:{}ms", System.currentTimeMillis() - beginTime);
return result;
}
}
}Execution result (sequential):
21:40:17.603 [main] INFO DemoTest$InterfaceA - 执行接口InterfaceA.process 耗时:2002ms
21:40:19.612 [main] INFO DemoTest$InterfaceB - 执行接口InterfaceB.process 耗时:2001ms
21:40:19.613 [main] INFO DemoTest - 执行结果:2 耗时:4018After Optimization – Asynchronous Calls with ThreadPoolExecutor
The refactored code submits each interface call to a fixed‑size thread pool and waits for the futures:
import cn.hutool.core.thread.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Slf4j
public class DemoTest {
private static ThreadPoolExecutor pool = new ThreadPoolExecutor(
5,
5,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1000),
ThreadFactoryBuilder.create().setNamePrefix("线程名称-").build()
);
public static void main(String[] args) throws Exception {
long beginTime = System.currentTimeMillis();
List<Future<Integer>> futures = new ArrayList<>(2);
List<Integer> results = new ArrayList<>(2);
futures.add(pool.submit(() -> new InterfaceA().process()));
futures.add(pool.submit(() -> new InterfaceB().process()));
for (Future<Integer> item : futures) {
results.add(item.get());
}
int result = results.get(0) + results.get(1);
log.info("执行结果:{} 耗时:{}", result, System.currentTimeMillis() - beginTime);
}
@Slf4j
public static final class InterfaceA { /* same as before */ }
@Slf4j
public static final class InterfaceB { /* same as before */ }
}Execution result (parallel):
22:03:43.180 [线程名称-1] INFO DemoTest$InterfaceB - 执行接口InterfaceB.process 耗时:2004ms
22:03:43.180 [线程名称-0] INFO DemoTest$InterfaceA - 执行接口InterfaceA.process 耗时:2004ms
22:03:43.190 [main] INFO DemoTest - 执行结果:2 耗时:2020Using CompletableFuture (JDK 1.8)
Java 8’s CompletableFuture can further simplify asynchronous composition:
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Slf4j
public class DemoTest {
public static void main(String[] args) throws Exception {
long beginTime = System.currentTimeMillis();
CompletableFuture<Integer> interfaceFuturesA = CompletableFuture.supplyAsync(() -> new InterfaceA().process());
CompletableFuture<Integer> interfaceFuturesB = CompletableFuture.supplyAsync(() -> new InterfaceB().process());
CompletableFuture<List<Integer>> future = CompletableFuture
.allOf(interfaceFuturesA, interfaceFuturesB)
.thenApply(none -> {
List<Integer> dataList = new ArrayList<>(2);
try {
dataList.add(interfaceFuturesA.get());
dataList.add(interfaceFuturesB.get());
} catch (Exception e) {
log.error("执行异常");
}
return dataList;
})
.exceptionally(e -> Lists.newArrayList());
int result = future.get().get(0) + future.get().get(1);
log.info("执行结果:{} 耗时:{}", result, System.currentTimeMillis() - beginTime);
}
@Slf4j
public static final class InterfaceA { /* same as before */ }
@Slf4j
public static final class InterfaceB { /* same as before */ }
}Result with CompletableFuture:
22:31:44.822 [ForkJoinPool.commonPool-worker-5] INFO DemoTest$InterfaceB - 执行接口InterfaceB.process 耗时:2005ms
22:31:44.822 [ForkJoinPool.commonPool-worker-3] INFO DemoTest$InterfaceA - 执行接口InterfaceA.process 耗时:2002ms
22:31:44.831 [main] INFO DemoTest - 执行结果:2 耗时:2027Optimization Tips
Use a thread pool to avoid memory‑overflow risks.
Customize the result container according to business needs.
Adjust interface granularity—combine or split calls based on actual workload.
By applying asynchronous execution, developers can significantly cut the total latency of multiple independent service calls while keeping the code maintainable.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
