java中可用泛型配合callable、future和线程池实现多线程任务结果封装,支持超时、异常处理、默认值兜底、批量聚合及completablefuture链式调用。

Java 中可以用泛型配合 Callable、Future 和线程池,实现通用的多线程任务结果封装。核心是让任务本身支持任意返回类型,同时统一处理执行、获取、超时、异常等逻辑。
定义泛型任务执行器
封装一个可复用的工具类,接受泛型任务并返回泛型结果:
- 使用
ExecutorService提交Callable<t></t>任务 - 用
Future<t></t>持有异步计算结果 - 提供带超时、重试、默认值等可选行为的方法
示例:
public class AsyncTaskExecutor {
private final ExecutorService executor;
public AsyncTaskExecutor(ExecutorService executor) {
this.executor = executor;
}
public <t> T execute(Callable<t> task) throws Exception {
return execute(task, 30, TimeUnit.SECONDS);
}
public <t> T execute(Callable<t> task, long timeout, TimeUnit unit) throws Exception {
Future<t> future = executor.submit(task);
try {
return future.get(timeout, unit);
} catch (TimeoutException e) {
future.cancel(true);
throw new RuntimeException("Task timed out", e);
} catch (ExecutionException e) {
throw e.getCause(); // 包装异常,抛出原始异常
}
}
}</t></t></t></t></t>
封装带默认值和异常兜底的泛型方法
实际使用中常需避免因单个任务失败导致整体阻塞或崩溃,可扩展为支持默认值和降级逻辑:
- 传入
Supplier<t></t>作为失败时的 fallback 值 - 对
ExecutionException或TimeoutException统一捕获并返回兜底结果 - 保持方法签名简洁,不暴露
Future细节
示例:
public <t> T executeWithFallback(
Callable<t> task,
T fallback,
long timeout,
TimeUnit unit) {
try {
Future<t> future = executor.submit(task);
return future.get(timeout, unit);
} catch (Exception e) {
return fallback;
}
}</t></t></t>
批量执行多个泛型任务并聚合结果
当需要并发执行一组不同类型的(但同构)任务时,可用 List<callable>></callable> + invokeAll:
- 所有任务返回相同类型
T,便于统一收集 -
executor.invokeAll()返回List<future>></future>,顺序与提交一致 - 遍历结果时注意检查
isDone()和get()异常
示例(获取一批用户 ID 对应的用户信息):
List<callable>> tasks = userIds.stream()
.map(id -> (Callable<user>) () -> userService.findById(id))
.collect(Collectors.toList());
List<future>> futures = executor.invokeAll(tasks);
List<user> results = new ArrayList();
for (Future<user> future : futures) {
try {
results.add(future.get(5, TimeUnit.SECONDS));
} catch (Exception e) {
results.add(null); // 或记录日志、加默认对象
}
}</user></user></future></user></callable>
配合 CompletableFuture 实现更灵活的链式泛型处理
若需组合、转换、异步回调,推荐用 CompletableFuture<t></t> 替代原始 Future:
-
supplyAsync(supplier, executor)直接启动泛型任务 -
thenApply、thenCompose等方法天然支持泛型链式转换 - 可统一异常处理:
exceptionally(Function<throwable t>)</throwable>
示例:
CompletableFuture<string> task = CompletableFuture
.supplyAsync(() -> fetchFromRemote(), executor)
.thenApply(String::toUpperCase)
.exceptionally(t -> "DEFAULT_VALUE");
String result = task.join(); // 阻塞获取,或用 thenAccept 异步消费</string>
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











