在 Java 中,FutureTask
类实现了Future
和 Runnable
接口,能够表示一个异步计算,也就是一个可以在另一个线程中执行的任务,其结果可通过 get()
方法获取。以下是一个示例,演示如何使用 FutureTask
:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureTaskExample {
public static void main(String[] args) {
Callable<Integer> task = () -> {
Thread.sleep(2000);
return 42;
};
FutureTask<Integer> futureTask = new FutureTask<>(task);
Thread thread = new Thread(futureTask);
thread.start();
try {
// 获取异步任务的结果,会阻塞直到任务完成
int result = futureTask.get();
System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
在这个示例中,我们首先创建一个Callable
对象 task
,表示一个异步计算逻辑,这里是模拟一个长时任务线程睡眠 2 秒后返回整数 42。接着我们创建一个FutureTask
对象futureTask
并将task
传递给它。
然后,我们将futureTask
对象交给一个新的线程thread
来执行,通过调用thread.start()
方法启动该线程。最后,我们使用futureTask.get()
方法来获取异步计算的结果,这个方法会一直阻塞直到计算完成,并返回计算的结果。
需要注意的是futureTask.get()
方法可能会抛出InterruptedException
和ExecutionException
异常,因此需要在调用时进行异常处理。
通过使用FutureTask
,我们可以方便地在多线程环境中执行异步任务,并获取任务的返回结果。
在 Java 中,Future
和 FutureTask
都是用于表示异步计算结果的接口或类,但它们之间有几个明显的区别:
- 接口 vs 类:
Future
是一个接口,它定义了一系列方法来操作异步计算的结果,例如get()
方法用于获取计算结果,cancel()
方法用于取消计算等。FutureTask
是一个实现了Future
和Runnable
接口的具体类,它提供了一个可以执行的任务,并允许获取任务的结果。
- 使用方法:
Future
接口主要用于表示异步计算的结果,并提供操作结果的方法。使用时,你需要将计算的结果设置到Future
对象中,并在需要时取回结果。通常需要和ExecutorService
结合使用。FutureTask
类实际上是一个可运行的任务,可以直接被执行。你可以将FutureTask
对象传递给一个线程来执行,并通过调用get()
方法来获取任务的执行结果。FutureTask
可以被用于包装Callable
或Runnable
,并可以由ExecutorService
执行。
- 可取消性:
Future
接口允许你取消任务的执行,通过调用cancel()
方法可以取消任务的执行。一旦任务被取消,isCancelled()
方法会返回true
。FutureTask
类也实现了可取消性,可以通过cancel()
方法来取消任务的执行。
总结来说,Future
主要是一个接口,用于表示异步计算的结果和操作结果,而FutureTask
是一个具体的类,实现了 Future
和 Runnable
接口,可以表示一个可执行的任务并获取任务的结果。在实际开发中,Future
通常和 ExecutorService
结合使用,而FutureTask
则是用于更为灵活的异步任务处理。