FutureTask是Java中用于封装异步任务的可取消计算单元,它实现Future和Runnable接口,能将Callable或Runnable包装为可获取结果、支持取消的任务。通过ExecutorService提交后,调用get()方法可阻塞获取结果,支持超时机制与异常处理(ExecutionException封装执行异常,CancellationException表示被取消)。相比传统线程管理,FutureTask优势在于统一的结果获取、状态查询(isDone/isCancelled)、规范的取消机制及与线程池的良好集成。但在复杂异步流程中,CompletableFuture凭借链式组合、非阻塞回调、手动完成和更优异常处理等特性,成为更现代的选择。FutureTask适用于简单异步任务,而CompletableFuture更适合构建响应式、多阶段的异步流水线。

Java中的
FutureTask
Callable
Runnable
Future
Runnable
使用
FutureTask
Callable
import java.util.concurrent.*;
// 1. 定义你的异步任务,这里我们用Callable,因为它能返回结果
class MyCallableTask implements Callable<String> {
private final String taskName;
private final long delayMillis;
public MyCallableTask(String taskName, long delayMillis) {
this.taskName = taskName;
this.delayMillis = delayMillis;
}
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName() + " - " + taskName + " 开始执行...");
try {
TimeUnit.MILLISECONDS.sleep(delayMillis); // 模拟耗时操作
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " - " + taskName + " 被中断。");
Thread.currentThread().interrupt(); // 重新设置中断标志
throw new InterruptedException("任务 " + taskName + " 被中断");
}
String result = "任务 " + taskName + " 完成,耗时 " + delayMillis + "ms。";
System.out.println(Thread.currentThread().getName() + " - " + result);
return result;
}
}
public class FutureTaskExample {
public static void main(String[] args) {
// 2. 创建一个Callable实例
MyCallableTask callableTask = new MyCallableTask("数据处理任务", 2000);
// 3. 将Callable包装成FutureTask
FutureTask<String> futureTask = new FutureTask<>(callableTask);
// 4. 提交FutureTask到一个ExecutorService(推荐方式)
// 或者也可以在一个新的线程中直接运行 futureTask.run();
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(futureTask); // submit方法会返回一个Future,但我们已经有了FutureTask实例
System.out.println("主线程已提交任务,正在做其他事情...");
try {
// 5. 获取任务结果,get()方法会阻塞直到任务完成
String result = futureTask.get(); // 也可以使用带超时参数的get(timeout, unit)
System.out.println("主线程获取到结果: " + result);
// 尝试取消一个任务(如果它还没开始或没完成)
MyCallableTask anotherTask = new MyCallableTask("耗时计算任务", 5000);
FutureTask<String> anotherFutureTask = new FutureTask<>(anotherTask);
executor.submit(anotherFutureTask);
System.out.println("尝试取消另一个任务...");
boolean cancelled = anotherFutureTask.cancel(true); // true表示如果任务正在运行,尝试中断它
System.out.println("任务是否被取消: " + cancelled);
// 检查被取消任务的状态
System.out.println("被取消任务是否完成: " + anotherFutureTask.isDone());
System.out.println("被取消任务是否真的被取消: " + anotherFutureTask.isCancelled());
try {
// 尝试获取被取消任务的结果,会抛出CancellationException
anotherFutureTask.get();
} catch (CancellationException e) {
System.out.println("意料之中:被取消的任务抛出了CancellationException。");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("主线程等待任务时被中断: " + e.getMessage());
} catch (ExecutionException e) {
System.err.println("任务执行过程中发生异常: " + e.getCause().getMessage());
} finally {
executor.shutdown(); // 关闭线程池
}
}
}这段代码展示了
FutureTask
get()
get()
CancellationException
get()
ExecutionException
getCause()
谈到
FutureTask
Thread
wait/notify
FutureTask
FutureTask
get()
立即学习“Java免费学习笔记(深入)”;
其次是任务状态的透明化管理。
isDone()
isCancelled()
Thread
再者,它对任务取消的支持也算是一个亮点。虽然
cancel(true)
InterruptedException
Thread.interrupt()
FutureTask
最后,
FutureTask
ExecutorService
FutureTask
new Thread()
在实际项目里,异步任务的异常和超时处理是绕不开的痛点,
FutureTask
异常处理: 当
Callable
FutureTask
futureTask.get()
ExecutionException
get()
// 假设有一个会抛出异常的Callable
class FailingTask implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("FailingTask 正在执行...");
throw new RuntimeException("Oops! 任务执行失败了!");
}
}
// 在主线程中
ExecutorService executor = Executors.newSingleThreadExecutor();
FutureTask<String> failingFutureTask = new FutureTask<>(new FailingTask());
executor.submit(failingFutureTask);
try {
String result = failingFutureTask.get();
System.out.println("任务成功: " + result);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("主线程被中断: " + e.getMessage());
} catch (ExecutionException e) {
// 捕获ExecutionException,并通过getCause()获取原始异常
System.err.println("任务执行异常,原始错误: " + e.getCause().getMessage());
// 这里可以根据e.getCause()的类型进行不同的处理,比如日志记录、重试、返回默认值等
} finally {
executor.shutdown();
}这种机制非常有用,它让异步任务的错误不再是“黑盒”,而是能够被清晰地传递回调用方。在我的经验里,通常会在这里根据
getCause()
超时处理:
FutureTask
get(long timeout, TimeUnit unit)
get()
TimeoutException
// 假设有一个耗时较长的Callable
class LongRunningTask implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("LongRunningTask 正在执行...");
TimeUnit.SECONDS.sleep(5); // 模拟5秒耗时
return "LongRunningTask 完成。";
}
}
// 在主线程中
ExecutorService executor = Executors.newSingleThreadExecutor();
FutureTask<String> longRunningFutureTask = new FutureTask<>(new LongRunningTask());
executor.submit(longRunningFutureTask);
try {
// 设置2秒的超时时间
String result = longRunningFutureTask.get(2, TimeUnit.SECONDS);
System.out.println("任务成功: " + result);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("主线程被中断: " + e.getMessage());
} catch (ExecutionException e) {
System.err.println("任务执行异常: " + e.getCause().getMessage());
} catch (TimeoutException e) {
System.err.println("任务执行超时!");
// 任务超时后,你可以选择取消它,防止它继续占用资源
boolean cancelled = longRunningFutureTask.cancel(true);
System.out.println("任务超时后是否尝试取消: " + cancelled);
} finally {
executor.shutdown();
}超时处理在很多场景下都至关重要,比如调用第三方服务、处理用户请求等。避免无限期等待不仅能提升用户体验,也能防止系统资源耗尽。当
TimeoutException
cancel(true)
在Java并发编程的演进中,
FutureTask
CompletableFuture
相似之处:
Future
get()
cancel()
不同之处(CompletableFuture
组合性与链式调用: 这是
CompletableFuture
FutureTask
FutureTask
Future
CompletableFuture
thenApply()
thenAccept()
thenCompose()
thenCombine()
allOf()
anyOf()
非阻塞回调:
FutureTask
get()
get()
isDone()
CompletableFuture
thenRun()
whenComplete()
手动完成:
CompletableFuture
complete(T value)
completeExceptionally(Throwable ex)
Callable
FutureTask
Callable
更丰富的异常处理:
CompletableFuture
exceptionally()
handle()
FutureTask
ExecutionException
何时选择?
选择FutureTask
FutureTask
ExecutorService
FutureTask
选择CompletableFuture
CompletableFuture
CompletableFuture
FutureTask
以上就是Java中FutureTask使用方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号