java中用callable和future创建带返回值的线程,核心是实现callable接口并通过executorservice提交任务获取future对象;callable支持泛型返回值和受检异常,future.get()阻塞获取结果,invokeall可批量执行并等待全部完成。

Java 中用 Callable 和 Future 创建带返回值的线程,核心是:不直接继承 Thread 或实现 Runnable,而是实现 Callable 接口,并通过线程池提交任务获得 Future 对象来获取结果。
1. 实现 Callable 接口(替代 Runnable)
Callable 和 Runnable 类似,但有两点关键区别:
- 它是一个泛型接口,
Callable<string></string>表示任务执行后返回String类型结果; - 它的
call()方法可以返回值,且允许抛出受检异常(Exception),而Runnable.run()既无返回值也不能抛受检异常。
示例:
// 定义一个返回整数的任务class MyTask implements Callable
public Integer call() throws Exception {
Thread.sleep(1000);
return 42;
}
}
2. 使用 ExecutorService 提交任务并获取 Future
Future 是对异步计算结果的占位符。你不能直接“启动” Callable,必须借助 ExecutorService(如 Executors.newFixedThreadPool(1))来执行:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
submit(Callable)方法返回Future<t></t>; - 调用
future.get()会阻塞当前线程,直到任务完成并返回结果; -
get(long, TimeUnit)可设置超时,避免无限等待; - 如果任务执行中抛出异常,
get()会以ExecutionException包装后抛出。
完整调用示例:
// 创建线程池ExecutorService executor = Executors.newFixedThreadPool(1);
// 提交 Callable 任务
Future
// 获取结果(会阻塞)
try {
Integer result = future.get();
System.out.println("结果:" + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
3. 多个 Callable 任务批量处理(用 invokeAll)
如果你有多个 Callable,想等全部完成再统一取结果,可用 invokeAll():
- 它接收
Collection extends Callable<t>></t>,返回List<future>></future>; - 该方法会阻塞,直到所有任务完成(或超时);
- 遍历返回的
Future列表,逐个调用get()即可拿到每个结果。
示例片段:
List() -> { Thread.sleep(500); return "A"; },
() -> { Thread.sleep(300); return "B"; }
);
List
for (Future
System.out.println(f.get());
}
4. 注意事项和常见问题
-
Future.get()是阻塞操作,别在主线程 UI 线程(如 Swing/JavaFX)中直接调用,否则界面卡死; -
isDone()可判断任务是否结束,isCancelled()判断是否被取消; - 调用
cancel(true)尝试中断正在运行的任务(依赖任务内部响应中断); -
Callable本身不启动线程,只是定义了“做什么”和“返回什么”,真正调度靠线程池; - 不要忘记关闭线程池(
shutdown()或shutdownNow()),防止资源泄漏。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










