callable仅声明任务逻辑,不执行;futuretask作为适配器包装callable并实现runnable/future,负责执行与结果缓存;future提供get()等方法安全获取结果;线程或线程池最终执行futuretask.run()触发call()。

Callable 接口本身不执行任务,也不管理线程,它只是定义了一个带返回值、可抛异常的 call() 方法。真正让“有返回值的异步任务”跑起来并拿到结果的,是一整套协作机制:Callable → FutureTask → 线程或线程池 → Future。
Callable 是任务逻辑的声明者
它只负责描述“要做什么、返回什么、可能出什么错”,不涉及执行时机、线程调度或结果暂存。比如:
Callable<string> task = () -> {
Thread.sleep(1000);
return "done";
};</string>
这段代码没启动任何线程,也没产生结果——它只是一个待执行的函数式任务契约。
FutureTask 是 Callable 的执行适配器
FutureTask 是 Callable 能被线程真正执行的关键桥梁。它同时实现 Runnable 和 Future 接口,把 Callable 包装成线程可识别的形式,并内置状态机和结果容器:
- 内部用
state字段记录任务状态(NEW / COMPLETING / NORMAL / EXCEPTIONAL / CANCELLED 等) - 用
outcome字段缓存call()的返回值,或用exception字段保存抛出的异常 - 调用
run()时才真正执行call(),并将结果写入outcome
Future 是结果的访问门面
你拿到的 Future 对象(通常是 FutureTask 实例),本质是结果的“只读句柄”。它的 get() 方法会:
- 检查
state是否已完成;未完成则阻塞当前线程(通过LockSupport.park()或wait()) - 完成后直接读取已缓存在
outcome中的值(或封装异常为ExecutionException) -
get(long, TimeUnit)还会配合超时等待与中断响应逻辑
线程池或 Thread 是实际执行载体
提交流程通常如下:
ExecutorService pool = Executors.newFixedThreadPool(1); Future<string> future = pool.submit(callable); // 内部 new FutureTask(callable) → execute(ftask) // 或 Thread t = new Thread(new FutureTask(callable)); t.start();</string>
无论哪种方式,最终都是 FutureTask 的 run() 被调用,触发 call() 执行,并将结果原子写入其内部字段。之后所有 future.get() 都只是安全读取这个已写好的字段。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











