在Java中实现并行请求通常涉及到多线程或者并发工具类的使用。以下是两种常见的并行请求模板:一种使用 ExecutorService
来管理线程池,另一种使用 Java 8 引入的 CompletableFuture
。
使用 ExecutorService 实现并行请求
以下是一个使用 ExecutorService
创建固定大小线程池,并发执行多个任务的模板:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ParallelRequestExecutor {
public void executeTasks(List<Runnable> tasks, int timeoutInSeconds) {
ExecutorService executorService = Executors.newFixedThreadPool(tasks.size());
try {
// 提交所有任务到线程池
for (Runnable task : tasks) {
executorService.submit(task);
}
// 关闭线程池,不再接受新任务
executorService.shutdown();
// 等待所有任务完成,或超时
if (!executorService.awaitTermination(timeoutInSeconds, TimeUnit.SECONDS)) {
executorService.shutdownNow(); // 超时后强制关闭
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt(); // 保持中断状态
}
}
}
使用 CompletableFuture 实现并行请求
另一种方法是使用 CompletableFuture
,这是Java 8引入的一个强大的并发工具,可以方便地处理异步编程问题。
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
public class ParallelRequestExecutor {
public void executeTasks(List<Runnable> tasks) {
List<CompletableFuture<Void>> futures = tasks.stream()
.map(task -> CompletableFuture.runAsync(task))
.collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
}
}
在这个示例中, CompletableFuture.runAsync
将每个任务异步地提交到 ForkJoinPool.commonPool()
中执行。然后 CompletableFuture.allOf
用于等待所有任务的完成。
注意事项
- 在使用线程池时,合理配置线程池的大小是非常重要的。线程池大小应该根据任务的类型和系统资源来决定。
CompletableFuture
提供了丰富的API来处理异步任务,包括异常处理、结果转换等。- 在任何情况下,确保正确处理异常和线程中断,以避免资源泄露或其他潜在问题。
- 对于 I/O 密集型任务(如HTTP请求),可以考虑使用比CPU核心数更多的线程;对于计算密集型任务,则通常设置线程数与CPU核心数相同。
这些并行请求模板可以根据您的具体需求进行调整和优化。