Java线程池通过Future获取异步任务状态,核心是isDone()、isCancelled()判断状态,get()获取结果(可超时),cancel()尝试取消;需注意中断响应与异常处理。

Java 中线程池通过 Future 获取异步任务执行状态,核心是调用 Future 提供的几个关键方法:检查是否完成、是否取消、是否被中断,以及尝试获取结果(可能阻塞)。下面分几块讲清楚怎么用、要注意什么。
提交任务并拿到 Future 对象
使用 ExecutorService 的 submit() 方法提交 Callable 或 Runnable 任务,会返回一个 Future 实例。这是后续查状态的基础:
-
submit(Callable<T> task)—— 返回Future<T>,适合有返回值的任务 -
submit(Runnable task, T result)—— 返回Future<T>,任务完成后返回指定 result -
submit(Runnable task)—— 返回Future<?>,结果始终为null
示例:
ExecutorService pool = Executors.newFixedThreadPool(2);Future<String> future = pool.submit(() -> {
Thread.sleep(1000);
return "done";
});
用 isDone() 和 isCancelled() 判断当前状态
isDone() 表示任务已结束(包括正常完成、异常退出或被取消);isCancelled() 表示任务在运行前就被 cancel(true) 取消了(注意:运行中强制中断不等于“已取消”,要看 cancel 是否成功返回 true):
立即学习“Java免费学习笔记(深入)”;
- 如果
isCancelled() == true,那么isDone() == true(取消属于结束的一种) - 如果
isDone() == true && isCancelled() == false,说明任务执行完了(无论成功或抛异常) -
isDone()为 false 时,任务还在运行中或尚未开始
建议轮询检查时加短延时(如 TimeUnit.MILLISECONDS.sleep(10)),避免空转消耗 CPU。
用 get() 获取结果并感知执行结果类型
future.get() 是阻塞式获取结果的方法,同时也能帮你区分三种终态:
- 正常返回:任务执行完毕,返回值即
Callable的结果 - 抛出
ExecutionException:任务内部抛出了异常(包装在该异常的 cause 中) - 抛出
CancellationException:任务被取消后调用get() - 抛出
InterruptedException:当前线程在等待时被中断
更安全的做法是用带超时的 get(long timeout, TimeUnit unit),避免无限等待:
String result = future.get(2, TimeUnit.SECONDS);
System.out.println("Success: " + result);
} catch (TimeoutException e) {
System.out.println("Task timed out");
} catch (ExecutionException e) {
System.err.println("Task failed: " + e.getCause());
} catch (InterruptedException | CancellationException e) {
System.err.println("Task interrupted or cancelled");
}
主动取消任务:cancel(boolean mayInterruptIfRunning)
调用 future.cancel(true) 尝试中断正在运行的线程(前提是任务逻辑响应中断,比如检查 Thread.interrupted() 或在阻塞点抛出 InterruptedException);cancel(false) 只对未启动的任务有效。
- 返回
true表示取消成功(任务还没开始,或已中断) - 返回
false表示任务已结束或无法取消(比如已运行完) - 即使 cancel(true) 返回 true,也不能保证线程立刻停止——需任务自身配合中断处理
所以,想可靠终止任务,得在 Callable 里定期检查中断状态,并及时退出。


















