futuretask 是 runnable 与 future 的桥梁,需用 callable 构造,支持结果获取、状态查询和取消;其为一次性对象,不可重用或重复提交。

Java 中可以通过 FutureTask 包装异步任务,再交给线程执行,从而获得任务结果、取消能力与状态查询功能。它本质是一个可被线程执行的 Runnable,同时实现了 Future 接口,是 Runnable 和 Future 的桥梁。
用 Callable 构造 FutureTask
FutureTask 必须包装一个 Callable(有返回值、可抛异常),不能直接包装普通 Runnable(除非用 Executors.callable(Runnable, result) 转换)。这是获取异步结果的前提。
- 定义一个实现
Callable<string></string>的任务,比如模拟耗时计算:
Callable
Thread.sleep(1000);
return "Done at " + System.currentTimeMillis();
};
```
- 用该
Callable创建FutureTask:
FutureTask
```
启动线程执行 FutureTask
FutureTask 自身实现了 Runnable,所以可以直接传给 Thread 构造器并启动:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
Thread thread = new Thread(futureTask);
thread.start();
```
此时任务在新线程中异步执行。注意:不要重复调用 start(),否则抛 IllegalThreadStateException;也不建议多次调用 run()(不会真正并发,且结果可能不一致)。
获取结果与控制任务生命周期
主线程可通过 FutureTask 实例查询状态、获取结果或尝试取消:
-
futureTask.isDone():任务是否已完成(正常结束、异常或被取消) -
futureTask.isCancelled():是否已被显式取消 -
futureTask.get():阻塞等待结果(可设超时,避免无限等待) -
futureTask.cancel(true):尝试取消任务;参数true表示中断运行中的线程
例如:
```javatry {
if (!futureTask.isDone()) {
System.out.println("任务还在跑...");
}
String result = futureTask.get(2, TimeUnit.SECONDS); // 最多等 2 秒
System.out.println("结果:" + result);
} catch (TimeoutException e) {
futureTask.cancel(true); // 超时则取消
System.out.println("任务超时,已取消");
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
```
注意事项与常见误区
-
FutureTask是一次性对象:一旦完成(无论成功、异常或取消),就不能重用;再次调用get()会立即返回缓存结果或异常 - 不要把同一个
FutureTask提交给多个线程:它内部状态不是为并发调用run()设计的,可能导致未定义行为 - 若需批量管理异步任务,推荐使用
ExecutorService(如Executors.newFixedThreadPool(3))配合submit(Callable),它底层也用FutureTask,但更安全、易扩展
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










