Java中Callable接口支持返回结果和抛出异常,需配合ExecutorService与Future使用;可提交单个任务通过future.get()获取结果,或批量调用invokeAll();还可结合CompletableFuture实现链式异步编排。

Java中使用Callable接口实现异步任务,核心在于它能返回结果并支持抛出异常,比Runnable更适用于需要获取执行结果的场景。通常配合ExecutorService和Future使用。
Callable接口的基本用法
Callable是一个泛型接口,只定义了一个call()方法,返回指定类型的值,且可声明抛出受检异常:
public interface Callable{ V call() throws Exception; }
例如,定义一个计算阶乘的异步任务:
CallablefactorialTask = () -> { long result = 1; for (int i = 1; i <= 5; i++) { result *= i; } return result; };
提交Callable任务并获取结果
通过ExecutorService的submit()方法提交Callable,返回Future对象,用于查询状态、获取结果或取消任务:
立即学习“Java免费学习笔记(深入)”;
- 调用
future.get()会阻塞当前线程,直到任务完成;可设置超时避免无限等待 - 调用
future.isDone()判断是否执行完毕 - 调用
future.cancel(true)尝试中断正在运行的任务
示例:
ExecutorService executor = Executors.newSingleThreadExecutor(); Futurefuture = executor.submit(factorialTask); try { Long result = future.get(3, TimeUnit.SECONDS); // 最多等3秒 System.out.println("结果:" + result); } catch (TimeoutException e) { System.out.println("任务超时"); } catch (ExecutionException | InterruptedException e) { e.printStackTrace(); } finally { executor.shutdown(); }
批量提交多个Callable任务
使用invokeAll()可一次性提交多个Callable,返回List,所有任务并发执行,方法调用会阻塞直到全部完成(或超时):
List> tasks = Arrays.asList( () -> { Thread.sleep(100); return 1; }, () -> { Thread.sleep(200); return 2; }, () -> { Thread.sleep(150); return 3; } ); List > futures = executor.invokeAll(tasks, 500, TimeUnit.MILLISECONDS); for (Future f : futures) { if (!f.isCancelled()) { System.out.println(f.get()); // 按提交顺序获取结果 } }
结合CompletableFuture做更灵活的异步编排
从Java 8起,CompletableFuture提供了更强大的异步编程能力,可替代原始Future的阻塞式等待:
- 用
CompletableFuture.supplyAsync()直接包装Callable逻辑(实际接受Supplier,但语义接近) - 支持链式调用:
thenApply、thenAccept、exceptionally等 - 可组合多个异步任务:
thenCompose、allOf、anyOf
示例:
CompletableFuturefuture = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); return "Hello"; } catch (InterruptedException e) { throw new RuntimeException(e); } }).thenApply(s -> s + " World") .exceptionally(t -> "Error: " + t.getMessage()); System.out.println(future.join()); // 非阻塞等待+获取结果










