java线程池通过submit(callable)提交有返回值任务并返回future,调用get()阻塞获取结果或异常,推荐使用带超时的get避免无限等待;批量任务可用invokeall统一提交与收集;需及时shutdown线程池并合理处理future资源。

Java 线程池提交 Callable 任务,核心是用 ExecutorService 的 submit() 方法,它会返回一个 Future 对象,用于获取异步执行结果、判断完成状态或主动取消任务。
用 submit(Callable) 获取 Future 并取返回值
Callable 和 Runnable 的关键区别在于:前者有返回值且可抛出受检异常。线程池不支持直接执行 Callable,但 submit() 方法专为此设计:
- 调用
executor.submit(myCallable)后立即返回Future<t></t>,不阻塞当前线程 -
Future.get()是阻塞操作,会等待任务完成并返回结果;若任务抛异常,get()会包装成ExecutionException抛出 - 建议配合超时使用
get(long timeout, TimeUnit unit),避免无限等待
实际代码示例(带异常和超时处理)
比如计算一个耗时的阶乘:
ExecutorService executor = Executors.newFixedThreadPool(2);
Callable<biginteger> task = () -> {
Thread.sleep(1000);
return factorial(10);
};
Future<biginteger> future = executor.submit(task);
try {
BigInteger result = future.get(3, TimeUnit.SECONDS); // 最多等3秒
System.out.println("结果:" + result);
} catch (TimeoutException e) {
System.out.println("任务超时,已取消");
future.cancel(true); // 中断正在执行的线程
} catch (ExecutionException e) {
System.err.println("任务执行出错:" + e.getCause());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
executor.shutdown();
}</biginteger></biginteger>
批量提交多个 Callable 并统一收集结果
当有多个独立 Callable 任务时,可用 invokeAll() 一次性提交,它返回 List<future>></future>,保证按提交顺序返回对应结果:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 所有任务并发执行,方法会阻塞直到全部完成(或超时)
- 每个
Future都需单独调用get()取值;即使某个任务失败,其他结果仍可获取 - 推荐设置合理超时,防止个别慢任务拖垮整体流程
注意点与最佳实践
别忘了关闭线程池:用完后调用 shutdown() 或 shutdownNow(),否则 JVM 不会退出;
Future 不是自动释放资源的句柄:未调用 get() 的 Future 仍会占用内存,长期堆积可能引发 OOM;
不要在 get() 前反复 isDone() 轮询:这属于低效忙等待,应直接用带超时的 get() 或配合 CompletableFuture 做异步编排;
如果需要链式处理、组合多个异步结果,建议升级到 CompletableFuture,它对 Callable 兼容良好,API 更灵活。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










