主线程同时调用多个接口,取到正确响应的,直接返回结果。主线程继续流程
核心代码:
public class MutilCallService {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
CompletionService<R> completionService = new ExecutorCompletionService<>(executor);
// List of callables for each interface call
List<Callable<R>> tasks = new ArrayList<>();
tasks.add(MutilCallService::callInterface1);
tasks.add(MutilCallService::callInterface1Fail);
tasks.add(MutilCallService::callInterface2);
tasks.add(MutilCallService::callInterface3);
try {
// Submit all tasks to the completion service
for (Callable<R> task : tasks) {
completionService.submit(task);
}
// Get the first successful result
String result = getFirstSuccessfulResult(completionService, tasks.size());
System.out.println("Fastest successful result: " + result);
} catch (Exception e) {
System.err.println("Failed to get a successful response: " + e.getMessage());
} finally {
executor.shutdown();
}
}
private static String getFirstSuccessfulResult(CompletionService<R> completionService, int taskCount) throws InterruptedException, ExecutionException {
for (int i = 0; i < taskCount; i++) {
try {
Future<R> future = completionService.take(); // Blocking call until a task completes
R result = future.get();
if (result.getCode().equals(200)) {
return result.getData().toString();
}
} catch (ExecutionException e) {
// Log the exception and continue to check the next result
System.err.println("Task failed: " + e.getCause());
}
}
throw new ExecutionException("No successful response received", null);
}
private static R callInterface1() {
// Simulate interface call
R r = new R();
try {
TimeUnit.SECONDS.sleep(5);
r.setCode(200);
r.setData("interface 1");
return r;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
r.setCode(500);
r.setData("interface 1");
return r;
}
}
private static R callInterface1Fail() {
// Simulate interface call
R r = new R();
try {
TimeUnit.SECONDS.sleep(1);
r.setCode(200);
r.setData("interface 1");
throw new Exception();
} catch (Exception e) {
Thread.currentThread().interrupt();
r.setCode(500);
r.setData("interface 1");
return r;
}
}
private static R callInterface2() {
// Simulate interface call
R r = new R();
try {
TimeUnit.SECONDS.sleep(2);
r.setCode(200);
r.setData("interface 2");
return r;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
r.setCode(500);
r.setData("interface 2");
return r;
}
}
private static R callInterface3() {
// Simulate interface call
R r = new R();
try {
TimeUnit.SECONDS.sleep(3);
r.setCode(200);
r.setData("interface 3");
return r;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
r.setCode(500);
r.setData("interface 3");
return r;
}
}
}
CompletionService 是 Java 并发包 (java.util.concurrent) 中的一个接口,用于管理和协调并发任务的执行。它将生产者和消费者模式与并发任务执行结合起来,使得处理一组并发任务的结果变得更加高效和简单。
具体来说,CompletionService 提供了以下主要功能:
提交任务:你可以将 Callable 或 Runnable 任务提交给 CompletionService,这些任务将由后台的 Executor 来执行。
获取任务结果:CompletionService 提供了方法来获取已完成任务的结果,不论这些任务提交的顺序如何,结果总是按任务完成的顺序返回。
CompletionService 有一个常见的实现类 ExecutorCompletionService,它通过一个现有的 Executor(如 ThreadPoolExecutor)来执行任务,并维护一个内部队列以保存已完成任务的结果。